@hermespilot/link 0.2.2 → 0.2.4

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/cli/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  startDaemonProcess,
27
27
  startLinkService,
28
28
  stopDaemonProcess
29
- } from "../chunk-4YF43CT4.js";
29
+ } from "../chunk-D55DPLGZ.js";
30
30
 
31
31
  // src/cli/index.ts
32
32
  import { Command } from "commander";
@@ -259,7 +259,7 @@ var messages = {
259
259
  "pair.linkId": "Hermes Link ID: {value}",
260
260
  "pair.code": "Pairing code: {value}",
261
261
  "pair.localApi": "Local API: http://127.0.0.1:{port}",
262
- "pair.scan": "Scan this QR code with the HermesPilot App:",
262
+ "pair.scan": "Open this pairing page in the HermesPilot App or scan the QR code below:",
263
263
  "pair.expires": "Pairing expires in 10 minutes. Press Ctrl+C to cancel waiting.",
264
264
  "pair.claimed": "Pairing succeeded. Starting Hermes Link in the background...",
265
265
  "pair.claimedRunning": "Pairing succeeded. Hermes Link is already running in the background.",
@@ -328,7 +328,7 @@ var messages = {
328
328
  "pair.linkId": "Hermes Link ID\uFF1A{value}",
329
329
  "pair.code": "\u914D\u5BF9\u7801\uFF1A{value}",
330
330
  "pair.localApi": "\u672C\u5730 API\uFF1Ahttp://127.0.0.1:{port}",
331
- "pair.scan": "\u8BF7\u4F7F\u7528 HermesPilot App \u626B\u63CF\u8FD9\u4E2A\u4E8C\u7EF4\u7801\uFF1A",
331
+ "pair.scan": "\u8BF7\u5728 HermesPilot App \u4E2D\u6253\u5F00\u8FD9\u4E2A\u914D\u5BF9\u9875\uFF0C\u6216\u626B\u63CF\u4E0B\u9762\u7684\u4E8C\u7EF4\u7801\uFF1A",
332
332
  "pair.expires": "\u914D\u5BF9\u4F1A\u8BDD 10 \u5206\u949F\u540E\u8FC7\u671F\u3002\u6309 Ctrl+C \u9000\u51FA\u7B49\u5F85\u3002",
333
333
  "pair.claimed": "\u914D\u5BF9\u5DF2\u6210\u529F\u3002\u6B63\u5728\u628A Hermes Link \u5207\u6362\u5230\u540E\u53F0\u8FD0\u884C...",
334
334
  "pair.claimedRunning": "\u914D\u5BF9\u5DF2\u6210\u529F\u3002Hermes Link \u5DF2\u5728\u540E\u53F0\u6301\u7EED\u8FD0\u884C\u3002",
@@ -557,6 +557,31 @@ function normalizeProfileName(profileName) {
557
557
  return value;
558
558
  }
559
559
 
560
+ // src/runtime/browser.ts
561
+ import { spawn } from "child_process";
562
+ async function openSystemBrowser(url) {
563
+ const platform = process.platform;
564
+ if (platform === "win32") {
565
+ return await spawnDetached("cmd", ["/c", "start", "", url]);
566
+ }
567
+ if (platform === "darwin") {
568
+ return await spawnDetached("open", [url]);
569
+ }
570
+ return await spawnDetached("xdg-open", [url]);
571
+ }
572
+ async function spawnDetached(command, args) {
573
+ try {
574
+ const child = spawn(command, args, {
575
+ detached: true,
576
+ stdio: "ignore"
577
+ });
578
+ child.unref();
579
+ return true;
580
+ } catch {
581
+ return false;
582
+ }
583
+ }
584
+
560
585
  // src/cli/index.ts
561
586
  var program = new Command();
562
587
  var helpLanguage = detectSystemLanguage();
@@ -661,10 +686,16 @@ program.command("pair").description(helpText("pair.description")).action(async (
661
686
  const restartReusedServiceAfterClaim = reusedRunningService && !probeBeforePair.linkId;
662
687
  const service = reusedRunningService ? null : await startLinkService({ paths });
663
688
  const qrValue = JSON.stringify(prepared.qrPayload);
689
+ const pairingPageUrl = `http://127.0.0.1:${config.port}/pair?session_id=${encodeURIComponent(prepared.sessionId)}`;
664
690
  console.log(t("pair.linkId", { value: prepared.linkId }));
665
691
  console.log(t("pair.code", { value: prepared.code }));
666
692
  console.log(t("pair.localApi", { port: config.port }));
693
+ if (!reusedRunningService) {
694
+ console.log(t("start.listening", { port: config.port }));
695
+ }
667
696
  console.log(t("pair.scan"));
697
+ console.log(`Pairing page: ${pairingPageUrl}`);
698
+ void openSystemBrowser(pairingPageUrl);
668
699
  qrcode.generate(qrValue, { small: true });
669
700
  console.log(t("pair.expires"));
670
701
  const result = await waitForPairingOrShutdown(prepared.sessionId, paths);
@@ -812,4 +843,3 @@ async function waitForPairingOrShutdown(sessionId, paths) {
812
843
  function sleep(ms) {
813
844
  return new Promise((resolve) => setTimeout(resolve, ms));
814
845
  }
815
- //# sourceMappingURL=index.js.map
@@ -9,6 +9,7 @@ interface RuntimePaths {
9
9
  databaseFile: string;
10
10
  conversationsDir: string;
11
11
  blobsDir: string;
12
+ deliveryStagingDir: string;
12
13
  indexesDir: string;
13
14
  logsDir: string;
14
15
  runDir: string;
@@ -153,6 +154,25 @@ interface LinkMessageAgentEvent {
153
154
  payload: unknown;
154
155
  };
155
156
  }
157
+ type LinkApprovalDecisionScope = 'once' | 'session' | 'always';
158
+ type LinkApprovalDecision = LinkApprovalDecisionScope | 'deny';
159
+ type LinkApprovalStatus = 'pending' | 'approved' | 'denied' | 'expired';
160
+ interface LinkApprovalRequest {
161
+ id: string;
162
+ status: LinkApprovalStatus;
163
+ kind: 'terminal_command';
164
+ command: string;
165
+ description?: string;
166
+ pattern_key?: string;
167
+ pattern_keys?: string[];
168
+ choices: LinkApprovalDecision[];
169
+ created_at: string;
170
+ resolved_at?: string;
171
+ decision?: LinkApprovalDecision;
172
+ resume_available: boolean;
173
+ resolution_hint?: string;
174
+ config_path?: string;
175
+ }
156
176
  interface LinkMessage {
157
177
  id: string;
158
178
  schema_version: 1;
@@ -173,6 +193,7 @@ interface LinkMessage {
173
193
  parts: LinkMessagePart[];
174
194
  attachments: unknown[];
175
195
  agent_events?: LinkMessageAgentEvent[];
196
+ approvals?: LinkApprovalRequest[];
176
197
  hermes?: Record<string, unknown>;
177
198
  raw?: {
178
199
  format: string;
@@ -211,6 +232,8 @@ interface LinkRun {
211
232
  id: string;
212
233
  kind?: 'agent' | 'command';
213
234
  hermes_run_id?: string;
235
+ hermes_response_id?: string;
236
+ previous_response_id?: string;
214
237
  conversation_id: string;
215
238
  trigger_message_id: string;
216
239
  assistant_message_id: string;
@@ -334,12 +357,37 @@ declare class ConversationService {
334
357
  conversation: ConversationSummary;
335
358
  last_event_seq: number;
336
359
  }>;
360
+ renameConversation(conversationId: string, title: string): Promise<{
361
+ conversation_id: string;
362
+ title: string;
363
+ conversation: ConversationSummary;
364
+ hermes_synced: boolean;
365
+ last_event_seq: number;
366
+ }>;
367
+ private renameConversationLocked;
337
368
  listEvents(conversationId: string, after?: number): Promise<ConversationEvent[]>;
338
369
  subscribe(conversationId: string, listener: ConversationEventListener): () => void;
339
370
  subscribeAll(listener: ConversationEventListener): () => void;
340
371
  sendMessage(input: SendMessageInput): Promise<SendMessageResult>;
341
372
  cancelRun(conversationId: string, runId: string): Promise<CancelRunResult>;
342
373
  cancelRunById(runId: string): Promise<CancelRunResult>;
374
+ resolveApproval(input: {
375
+ conversationId: string;
376
+ approvalId: string;
377
+ decision: LinkApprovalDecision;
378
+ }): Promise<{
379
+ conversation_id: string;
380
+ message_id: string;
381
+ approval: LinkApprovalRequest;
382
+ command_allowlist_updated: boolean;
383
+ config_path?: string;
384
+ requires_gateway_reload: boolean;
385
+ gateway_reloaded?: boolean;
386
+ reload_error?: string;
387
+ restart_hint?: string;
388
+ resume_available: boolean;
389
+ last_event_seq: number;
390
+ }>;
343
391
  deleteConversation(conversationId: string): Promise<DeleteConversationResult>;
344
392
  deleteConversations(conversationIds: string[]): Promise<{
345
393
  deleted_count: number;
@@ -373,7 +421,6 @@ declare class ConversationService {
373
421
  deleted: boolean;
374
422
  blob_id: string;
375
423
  }>;
376
- private refreshTitleFromHermesWithRetries;
377
424
  private refreshTitleFromHermes;
378
425
  private persistConversationStats;
379
426
  private appendEvent;
package/dist/http/app.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-4YF43CT4.js";
3
+ } from "../chunk-D55DPLGZ.js";
4
4
  export {
5
5
  createApp
6
6
  };
7
- //# sourceMappingURL=app.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hermespilot/link",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",
@@ -27,7 +27,7 @@
27
27
  "access": "public"
28
28
  },
29
29
  "scripts": {
30
- "build": "tsup src/cli/index.ts src/http/app.ts --format esm --target node22 --dts --sourcemap --clean",
30
+ "build": "tsup src/cli/index.ts src/http/app.ts --format esm --target node22 --dts --clean",
31
31
  "check": "tsc --noEmit",
32
32
  "dev": "tsx src/cli/index.ts",
33
33
  "preinstall": "node ./scripts/check-node-version.mjs",
@@ -43,6 +43,7 @@
43
43
  "@koa/router": "^15.4.0",
44
44
  "commander": "^12.1.0",
45
45
  "koa": "^2.15.3",
46
+ "qrcode": "^1.5.4",
46
47
  "qrcode-terminal": "^0.12.0",
47
48
  "ws": "^8.18.0",
48
49
  "yaml": "^2.6.1",
@@ -51,6 +52,7 @@
51
52
  "devDependencies": {
52
53
  "@types/koa": "^2.15.0",
53
54
  "@types/node": "^22.10.2",
55
+ "@types/qrcode": "^1.5.6",
54
56
  "@types/qrcode-terminal": "^0.12.2",
55
57
  "@types/ws": "^8.5.13",
56
58
  "tsup": "^8.3.5",