@hermespilot/link 0.3.9 → 0.4.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/{chunk-7OVDWXR7.js → chunk-476X63MC.js} +930 -218
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +88 -49
- package/dist/http/app.d.ts +18 -15
- package/dist/http/app.js +1 -1
- package/dist/paths-CmAiZsna.d.ts +16 -0
- package/package.json +1 -1
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
LINK_VERSION,
|
|
6
6
|
LinkHttpError,
|
|
7
7
|
clearPairingClaim,
|
|
8
|
+
connectRelayControl,
|
|
8
9
|
createFileLogger,
|
|
9
10
|
currentCliScriptPath,
|
|
10
11
|
daemonLogFile,
|
|
@@ -33,10 +34,11 @@ import {
|
|
|
33
34
|
startDaemonProcess,
|
|
34
35
|
startLinkService,
|
|
35
36
|
stopDaemonProcess
|
|
36
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-476X63MC.js";
|
|
37
38
|
|
|
38
39
|
// src/cli/index.ts
|
|
39
40
|
import { Command } from "commander";
|
|
41
|
+
import path3 from "path";
|
|
40
42
|
import { createInterface } from "readline/promises";
|
|
41
43
|
import qrcode from "qrcode-terminal";
|
|
42
44
|
|
|
@@ -285,6 +287,7 @@ var messages = {
|
|
|
285
287
|
"pair.openPairingPage": "If the QR code is hard to scan, you can open this page locally: {url}",
|
|
286
288
|
"pair.manualCode": "You can also use the HermesPilot App manual connection mode and enter this pairing code:",
|
|
287
289
|
"pair.expires": "Pairing expires in 10 minutes. Press Ctrl+C to cancel waiting.",
|
|
290
|
+
"pair.expired": "Pairing expired. Please run `hermeslink pair` again.",
|
|
288
291
|
"pair.claimed": "Pairing succeeded. Starting Hermes Link in the background...",
|
|
289
292
|
"pair.claimedRunning": "Pairing succeeded. Hermes Link is already running in the background.",
|
|
290
293
|
"pair.relayOnlyNotice": "Network note: this {kind} environment does not expose a phone-reachable LAN/public direct address by default. The App will connect through Relay.",
|
|
@@ -379,6 +382,7 @@ var messages = {
|
|
|
379
382
|
"pair.openPairingPage": "\u5982\u679C\u4E8C\u7EF4\u7801\u4E0D\u5BB9\u6613\u626B\u63CF\uFF0C\u4F60\u53EF\u4EE5\u5728\u672C\u673A\u6253\u5F00\u8FD9\u4E2A\u9875\u9762\uFF1A{url}",
|
|
380
383
|
"pair.manualCode": "\u4F60\u4E5F\u53EF\u4EE5\u5728 HermesPilot App \u4E2D\u4F7F\u7528\u624B\u52A8\u8FDE\u63A5\u6A21\u5F0F\uFF0C\u8F93\u5165\u4EE5\u4E0B\u914D\u5BF9\u7801\u8FDB\u884C\u8FDE\u63A5\uFF1A",
|
|
381
384
|
"pair.expires": "\u914D\u5BF9\u4F1A\u8BDD 10 \u5206\u949F\u540E\u8FC7\u671F\u3002\u6309 Ctrl+C \u9000\u51FA\u7B49\u5F85\u3002",
|
|
385
|
+
"pair.expired": "\u914D\u5BF9\u4F1A\u8BDD\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C `hermeslink pair`\u3002",
|
|
382
386
|
"pair.claimed": "\u914D\u5BF9\u5DF2\u6210\u529F\u3002\u6B63\u5728\u628A Hermes Link \u5207\u6362\u5230\u540E\u53F0\u8FD0\u884C...",
|
|
383
387
|
"pair.claimedRunning": "\u914D\u5BF9\u5DF2\u6210\u529F\u3002Hermes Link \u5DF2\u5728\u540E\u53F0\u6301\u7EED\u8FD0\u884C\u3002",
|
|
384
388
|
"pair.relayOnlyNotice": "\u7F51\u7EDC\u63D0\u793A\uFF1A\u5F53\u524D\u662F {kind} \u73AF\u5883\uFF0C\u9ED8\u8BA4\u4E0D\u4F1A\u66B4\u9732\u624B\u673A\u53EF\u8BBF\u95EE\u7684\u5C40\u57DF\u7F51\u6216\u516C\u7F51\u76F4\u8FDE\u5730\u5740\u3002App \u4F1A\u901A\u8FC7 Relay \u8FDE\u63A5\u3002",
|
|
@@ -847,55 +851,77 @@ program.command("pair").description(helpText("pair.description")).action(async (
|
|
|
847
851
|
}
|
|
848
852
|
const reusedRunningService = probe.reusable;
|
|
849
853
|
const restartReusedServiceAfterClaim = reusedRunningService && !probeBeforePair.linkId;
|
|
850
|
-
const service = reusedRunningService ? null : await startLinkService({
|
|
854
|
+
const service = reusedRunningService ? null : await startLinkService({
|
|
855
|
+
paths,
|
|
856
|
+
waitForRelayReady: true
|
|
857
|
+
});
|
|
858
|
+
let pairingRelayBridge = null;
|
|
859
|
+
if (restartReusedServiceAfterClaim) {
|
|
860
|
+
pairingRelayBridge = connectRelayControl({
|
|
861
|
+
relayBaseUrl: prepared.relayBaseUrl,
|
|
862
|
+
linkId: prepared.linkId,
|
|
863
|
+
localPort: config.port
|
|
864
|
+
});
|
|
865
|
+
pairingRelayBridge.publishNetworkRoutes(prepared.routes);
|
|
866
|
+
}
|
|
851
867
|
const qrValue = JSON.stringify(prepared.qrPayload);
|
|
852
868
|
const pairingPageUrl = `http://127.0.0.1:${config.port}/pair?session_id=${encodeURIComponent(prepared.sessionId)}`;
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
method: currentAutostart.method,
|
|
877
|
-
path: currentAutostart.filePath ?? ""
|
|
878
|
-
})
|
|
879
|
-
);
|
|
869
|
+
try {
|
|
870
|
+
console.log(t("pair.scan"));
|
|
871
|
+
qrcode.generate(qrValue, { small: true });
|
|
872
|
+
await openSystemBrowser(pairingPageUrl);
|
|
873
|
+
console.log(t("pair.openPairingPage", { url: pairingPageUrl }));
|
|
874
|
+
console.log(t("pair.manualCode"));
|
|
875
|
+
console.log(prepared.code);
|
|
876
|
+
console.log(t("pair.expires"));
|
|
877
|
+
const result = await waitForPairingOrShutdown(
|
|
878
|
+
prepared.sessionId,
|
|
879
|
+
prepared.expiresAt,
|
|
880
|
+
paths
|
|
881
|
+
);
|
|
882
|
+
if (service) {
|
|
883
|
+
await service.close();
|
|
884
|
+
}
|
|
885
|
+
if (result === "claimed") {
|
|
886
|
+
await clearPairingClaim(prepared.sessionId, paths);
|
|
887
|
+
console.log(t(reusedRunningService ? "pair.claimedRunning" : "pair.claimed"));
|
|
888
|
+
printPostPairingNetworkNotice(prepared.routes.environment, config, t);
|
|
889
|
+
try {
|
|
890
|
+
if (hadActiveDevices) {
|
|
891
|
+
console.log(t("pair.autostartUnchanged"));
|
|
880
892
|
} else {
|
|
881
|
-
const
|
|
882
|
-
if (
|
|
883
|
-
console.log(
|
|
893
|
+
const currentAutostart = await getAutostartStatus();
|
|
894
|
+
if (currentAutostart.supported && currentAutostart.enabled) {
|
|
895
|
+
console.log(
|
|
896
|
+
t("autostart.alreadyEnabled", {
|
|
897
|
+
method: currentAutostart.method,
|
|
898
|
+
path: currentAutostart.filePath ?? ""
|
|
899
|
+
})
|
|
900
|
+
);
|
|
901
|
+
} else {
|
|
902
|
+
const autostart2 = await enableAutostart();
|
|
903
|
+
if (autostart2.supported && autostart2.enabled) {
|
|
904
|
+
console.log(t("autostart.enabled", { method: autostart2.method, path: autostart2.filePath ?? "" }));
|
|
905
|
+
}
|
|
884
906
|
}
|
|
885
907
|
}
|
|
908
|
+
} catch (error) {
|
|
909
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
910
|
+
console.log(t("pair.autostartFailed", { message }));
|
|
886
911
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
} else if (
|
|
896
|
-
|
|
897
|
-
console.log(t("start.backgroundStarted", { pid: status.pid ?? "unknown" }));
|
|
912
|
+
if (restartReusedServiceAfterClaim) {
|
|
913
|
+
await stopDaemonProcess(paths);
|
|
914
|
+
const status = await startDaemonProcess(paths);
|
|
915
|
+
console.log(t("start.backgroundStarted", { pid: status.pid ?? "unknown" }));
|
|
916
|
+
} else if (!reusedRunningService) {
|
|
917
|
+
const status = await startDaemonProcess(paths);
|
|
918
|
+
console.log(t("start.backgroundStarted", { pid: status.pid ?? "unknown" }));
|
|
919
|
+
}
|
|
920
|
+
} else if (result === "expired") {
|
|
921
|
+
console.log(t("pair.expired"));
|
|
898
922
|
}
|
|
923
|
+
} finally {
|
|
924
|
+
pairingRelayBridge?.close();
|
|
899
925
|
}
|
|
900
926
|
});
|
|
901
927
|
var autostart = program.command("autostart").description(helpText("autostart.description"));
|
|
@@ -973,11 +999,13 @@ program.command("doctor").description(helpText("doctor.description")).action(asy
|
|
|
973
999
|
console.log(t("doctor.apiUnavailable", { message: error instanceof Error ? error.message : String(error) }));
|
|
974
1000
|
}
|
|
975
1001
|
});
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1002
|
+
if (isCliEntrypoint()) {
|
|
1003
|
+
program.parseAsync(process.argv).catch(async (error) => {
|
|
1004
|
+
const language = await loadCliLanguage().catch(() => detectSystemLanguage());
|
|
1005
|
+
console.error(localizeErrorMessage(error, language));
|
|
1006
|
+
process.exitCode = 1;
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
981
1009
|
async function loadCliLanguage() {
|
|
982
1010
|
const config = await loadConfig();
|
|
983
1011
|
return resolveLanguage(config.language);
|
|
@@ -1083,8 +1111,9 @@ async function waitForShutdown(cleanup) {
|
|
|
1083
1111
|
});
|
|
1084
1112
|
await cleanup();
|
|
1085
1113
|
}
|
|
1086
|
-
async function waitForPairingOrShutdown(sessionId, paths) {
|
|
1114
|
+
async function waitForPairingOrShutdown(sessionId, expiresAt, paths) {
|
|
1087
1115
|
let shutdownRequested = false;
|
|
1116
|
+
const expiresAtMs = Date.parse(expiresAt);
|
|
1088
1117
|
const stop = () => {
|
|
1089
1118
|
shutdownRequested = true;
|
|
1090
1119
|
};
|
|
@@ -1092,6 +1121,9 @@ async function waitForPairingOrShutdown(sessionId, paths) {
|
|
|
1092
1121
|
process.once("SIGTERM", stop);
|
|
1093
1122
|
try {
|
|
1094
1123
|
while (!shutdownRequested) {
|
|
1124
|
+
if (Number.isFinite(expiresAtMs) && Date.now() >= expiresAtMs) {
|
|
1125
|
+
return "expired";
|
|
1126
|
+
}
|
|
1095
1127
|
const record = await readPairingClaim(sessionId, paths);
|
|
1096
1128
|
if (record) {
|
|
1097
1129
|
return "claimed";
|
|
@@ -1124,3 +1156,10 @@ function printPostPairingNetworkNotice(environment, config, t) {
|
|
|
1124
1156
|
console.log(t("pair.relayOnlyLanHostHint"));
|
|
1125
1157
|
console.log(t("pair.relayOnlySafetyHint"));
|
|
1126
1158
|
}
|
|
1159
|
+
function isCliEntrypoint() {
|
|
1160
|
+
const entry = process.argv[1];
|
|
1161
|
+
return Boolean(entry && import.meta.url === new URL(`file://${path3.resolve(entry)}`).href);
|
|
1162
|
+
}
|
|
1163
|
+
export {
|
|
1164
|
+
waitForPairingOrShutdown
|
|
1165
|
+
};
|
package/dist/http/app.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Koa from 'koa';
|
|
2
|
+
import { R as RuntimePaths } from '../paths-CmAiZsna.js';
|
|
2
3
|
|
|
3
4
|
interface ConversationProfileSummary {
|
|
4
5
|
uid?: string;
|
|
@@ -183,6 +184,19 @@ interface BulkDeleteConversationResult {
|
|
|
183
184
|
message: string;
|
|
184
185
|
};
|
|
185
186
|
}
|
|
187
|
+
type ConversationClearPlanStatus = 'prepared' | 'executing' | 'completed' | 'failed';
|
|
188
|
+
interface ConversationClearPlan {
|
|
189
|
+
id: string;
|
|
190
|
+
status: ConversationClearPlanStatus;
|
|
191
|
+
created_at: string;
|
|
192
|
+
updated_at: string;
|
|
193
|
+
total_count: number;
|
|
194
|
+
deleted_count: number;
|
|
195
|
+
failed_count: number;
|
|
196
|
+
conversation_ids: string[];
|
|
197
|
+
conversations: BulkDeleteConversationResult[];
|
|
198
|
+
completed_at?: string;
|
|
199
|
+
}
|
|
186
200
|
interface LinkRun {
|
|
187
201
|
id: string;
|
|
188
202
|
kind?: 'agent' | 'command';
|
|
@@ -254,21 +268,6 @@ interface CancelRunResult {
|
|
|
254
268
|
}
|
|
255
269
|
type ConversationEventListener = (event: ConversationEvent) => void;
|
|
256
270
|
|
|
257
|
-
interface RuntimePaths {
|
|
258
|
-
homeDir: string;
|
|
259
|
-
identityFile: string;
|
|
260
|
-
configFile: string;
|
|
261
|
-
stateFile: string;
|
|
262
|
-
credentialsFile: string;
|
|
263
|
-
databaseFile: string;
|
|
264
|
-
conversationsDir: string;
|
|
265
|
-
blobsDir: string;
|
|
266
|
-
indexesDir: string;
|
|
267
|
-
logsDir: string;
|
|
268
|
-
runDir: string;
|
|
269
|
-
pairingDir: string;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
271
|
interface LinkStatistics {
|
|
273
272
|
conversations: {
|
|
274
273
|
total: number;
|
|
@@ -462,6 +461,10 @@ declare class ConversationService {
|
|
|
462
461
|
last_event_seq: number;
|
|
463
462
|
}>;
|
|
464
463
|
deleteConversation(conversationId: string): Promise<DeleteConversationResult>;
|
|
464
|
+
prepareClearAllConversationPlan(): Promise<ConversationClearPlan>;
|
|
465
|
+
readClearAllConversationPlan(planId: string): Promise<ConversationClearPlan>;
|
|
466
|
+
executeClearAllConversationPlan(planId: string): Promise<ConversationClearPlan>;
|
|
467
|
+
startClearAllConversationPlan(planId: string): Promise<ConversationClearPlan>;
|
|
465
468
|
deleteConversations(conversationIds: string[]): Promise<{
|
|
466
469
|
deleted_count: number;
|
|
467
470
|
failed_count: number;
|
package/dist/http/app.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface RuntimePaths {
|
|
2
|
+
homeDir: string;
|
|
3
|
+
identityFile: string;
|
|
4
|
+
configFile: string;
|
|
5
|
+
stateFile: string;
|
|
6
|
+
credentialsFile: string;
|
|
7
|
+
databaseFile: string;
|
|
8
|
+
conversationsDir: string;
|
|
9
|
+
blobsDir: string;
|
|
10
|
+
indexesDir: string;
|
|
11
|
+
logsDir: string;
|
|
12
|
+
runDir: string;
|
|
13
|
+
pairingDir: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type { RuntimePaths as R };
|