@yancyyu/openhermit 1.6.13 → 1.6.14

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.
@@ -1,8 +1,8 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import path from 'node:path';
3
- import { pathToFileURL } from 'node:url';
3
+ import { fileURLToPath, pathToFileURL } from 'node:url';
4
4
 
5
- const repoRoot = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
5
+ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
6
6
 
7
7
  const ALIASES = [
8
8
  ['@features/', 'src/features/'],
package/bin/hermit.mjs CHANGED
@@ -55,7 +55,7 @@ Usage:
55
55
 
56
56
  Options:
57
57
  --port <number> HTTP server port (default: 5680)
58
- --no-cc-connect Do not auto-start bundled cc-connect
58
+ --no-cc-connect Do not auto-start bundled runtime service
59
59
  --daemon Run openHermit in the background
60
60
  --version Show current version
61
61
  --help Show this help message
@@ -517,10 +517,10 @@ if (!skipCcConnect) {
517
517
  const ccBaseUrl = process.env.CC_CONNECT_BASE_URL || 'http://127.0.0.1:9820';
518
518
  const alreadyRunning = await waitForCcConnect(ccBaseUrl, ccTokens.managementToken, 1_000);
519
519
  if (alreadyRunning) {
520
- console.log(`[openHermit] cc-connect already running: ${ccBaseUrl}`);
520
+ console.log(`[openHermit] Runtime service already running: ${ccBaseUrl}`);
521
521
  } else {
522
- console.log('[openHermit] Starting bundled cc-connect...');
523
- console.log(`[openHermit] cc-connect config: ${ccConnectConfigPath}`);
522
+ console.log('[openHermit] Starting bundled runtime service...');
523
+ console.log(`[openHermit] Runtime config: ${ccConnectConfigPath}`);
524
524
  ccConnectProcess = spawn(process.execPath, [resolveCcConnectRunner(), '-config', ccConnectConfigPath], {
525
525
  cwd: repoRoot,
526
526
  detached: true,
@@ -534,7 +534,7 @@ if (!skipCcConnect) {
534
534
  });
535
535
  const ready = await waitForCcConnect(ccBaseUrl, ccTokens.managementToken, 30_000);
536
536
  if (!ready) {
537
- console.warn('[openHermit] cc-connect did not become ready within 30s; openHermit will keep trying via API.');
537
+ console.warn('[openHermit] Runtime service did not become ready within 30s; openHermit will keep trying via API.');
538
538
  }
539
539
  }
540
540
  }
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync } from 'node:fs';
4
+ import { createRequire } from 'node:module';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
11
+
12
+ let version = 'unknown';
13
+ try {
14
+ version = JSON.parse(readFileSync(path.join(packageRoot, 'package.json'), 'utf-8')).version;
15
+ } catch {
16
+ // Keep install non-blocking.
17
+ }
18
+
19
+ let runtimeVersion = 'bundled';
20
+ try {
21
+ runtimeVersion = JSON.parse(readFileSync(require.resolve('cc-connect/package.json'), 'utf-8')).version;
22
+ } catch {
23
+ // Keep install non-blocking.
24
+ }
25
+
26
+ const hermitHome = process.env.HERMIT_HOME || path.join(os.homedir(), '.hermit');
27
+
28
+ console.log(`[openHermit] Installed ${version}`);
29
+ console.log(`[openHermit] Bundled runtime service: ${runtimeVersion}`);
30
+ console.log(`[openHermit] Data directory: ${hermitHome}`);
31
+ console.log('[openHermit] Start with: openhermit');
32
+ console.log('[openHermit] Background mode: openhermit --daemon');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yancyyu/openhermit",
3
3
  "type": "module",
4
- "version": "1.6.13",
4
+ "version": "1.6.14",
5
5
  "description": "openHermit: team-oriented agent management workbench atop cc-connect.",
6
6
  "license": "AGPL-3.0",
7
7
  "author": {
@@ -34,6 +34,7 @@
34
34
  "dev:server": "tsx watch src/main/server.ts",
35
35
  "dev:web": "vite --config vite.web.config.ts",
36
36
  "build:web": "vite build --config vite.web.config.ts --outDir ../../dist-renderer --emptyOutDir",
37
+ "postinstall": "node ./bin/postinstall.mjs",
37
38
  "prepack": "pnpm build:web",
38
39
  "start": "node bin/hermit.mjs",
39
40
  "typecheck": "tsc --noEmit",
@@ -1033,11 +1033,10 @@ app.delete<{ Params: { name: string }; Querystring: { deleteFiles?: string } }>(
1033
1033
  async (request, reply) => {
1034
1034
  const teamName = request.params.name;
1035
1035
  try {
1036
+ let restartRequired = false;
1036
1037
  try {
1037
1038
  const result = await cc.deleteProject(teamName);
1038
- if (result.restart_required) {
1039
- await cc.restart();
1040
- }
1039
+ restartRequired = result.restart_required === true;
1041
1040
  } catch (err) {
1042
1041
  request.log.warn({ err, teamName }, 'delete cc-connect project failed or project missing');
1043
1042
  }
@@ -1048,7 +1047,7 @@ app.delete<{ Params: { name: string }; Querystring: { deleteFiles?: string } }>(
1048
1047
  request.log.warn({ err, teamName }, 'delete local team metadata failed or already missing');
1049
1048
  }
1050
1049
 
1051
- return { ok: true, restartRequired: false };
1050
+ return { ok: true, restartRequired };
1052
1051
  } catch (err) {
1053
1052
  return reply.code(500).send(reply500(err));
1054
1053
  }
@@ -7,6 +7,8 @@
7
7
 
8
8
  import { useCallback, useEffect, useState } from 'react';
9
9
 
10
+ import { api } from '@renderer/api';
11
+ import { confirm } from '@renderer/components/common/ConfirmDialog';
10
12
  import { Button } from '@renderer/components/ui/button';
11
13
  import {
12
14
  Dialog,
@@ -198,14 +200,20 @@ async function addPlatform(
198
200
  projectName: string,
199
201
  type: string,
200
202
  options: Record<string, string>
201
- ): Promise<void> {
203
+ ): Promise<{ restartRequired: boolean }> {
202
204
  const res = await fetch(`/api/v1/projects/${encodeURIComponent(projectName)}/add-platform`, {
203
205
  method: 'POST',
204
206
  headers: { 'Content-Type': 'application/json' },
205
207
  body: JSON.stringify({ type, options }),
206
208
  });
207
- const json = (await res.json()) as { ok: boolean; error?: string };
209
+ const json = (await res.json()) as {
210
+ ok: boolean;
211
+ error?: string;
212
+ data?: { restart_required?: boolean };
213
+ restart_required?: boolean;
214
+ };
208
215
  if (!json.ok) throw new Error(json.error ?? '添加失败');
216
+ return { restartRequired: json.data?.restart_required === true || json.restart_required === true };
209
217
  }
210
218
 
211
219
  // ---------------------------------------------------------------------------
@@ -482,8 +490,19 @@ function AddPlatformDialog({
482
490
  else if (v === 'false') ccOptions[k] = false;
483
491
  else ccOptions[k] = v;
484
492
  }
485
- await addPlatform(projectName, platformType, ccOptions as Record<string, string>);
493
+ const result = await addPlatform(projectName, platformType, ccOptions as Record<string, string>);
486
494
  onAdded(projectName);
495
+ if (result.restartRequired) {
496
+ const shouldRestart = await confirm({
497
+ title: '重启 cc-connect',
498
+ message: '渠道已添加。需要重启 cc-connect 才会生效。',
499
+ confirmLabel: '立即重启',
500
+ cancelLabel: '稍后重启',
501
+ });
502
+ if (shouldRestart) {
503
+ await api.ccSettings.restart();
504
+ }
505
+ }
487
506
  } catch (e) {
488
507
  setError(e instanceof Error ? e.message : '添加失败');
489
508
  } finally {
@@ -1830,7 +1830,19 @@ export const TeamDetailView = ({
1830
1830
  setDeleteConfirmOpen(false);
1831
1831
  void (async () => {
1832
1832
  try {
1833
- await deleteTeam(teamName);
1833
+ const result = await deleteTeam(teamName);
1834
+ if (result.restartRequired) {
1835
+ const shouldRestart = await confirm({
1836
+ title: '重启 cc-connect',
1837
+ message: '团队已从配置中删除。需要重启 cc-connect 才会停止对应运行时。',
1838
+ confirmLabel: '立即重启',
1839
+ cancelLabel: '稍后重启',
1840
+ variant: 'danger',
1841
+ });
1842
+ if (shouldRestart) {
1843
+ await api.ccSettings.restart();
1844
+ }
1845
+ }
1834
1846
  if (tabId) closeTab(tabId);
1835
1847
  openTeamsTab();
1836
1848
  } catch {
@@ -539,7 +539,19 @@ export const TeamListView = (): React.JSX.Element => {
539
539
  });
540
540
  if (confirmed) {
541
541
  try {
542
- await deleteTeam(teamName);
542
+ const result = await deleteTeam(teamName);
543
+ if (result.restartRequired) {
544
+ const shouldRestart = await confirm({
545
+ title: '重启 cc-connect',
546
+ message: '团队已从配置中删除。需要重启 cc-connect 才会停止对应运行时。',
547
+ confirmLabel: '立即重启',
548
+ cancelLabel: '稍后重启',
549
+ variant: 'danger',
550
+ });
551
+ if (shouldRestart) {
552
+ await api.ccSettings.restart();
553
+ }
554
+ }
543
555
  } catch {
544
556
  // error via store
545
557
  }