@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.
- package/bin/alias-loader.mjs +2 -2
- package/bin/hermit.mjs +5 -5
- package/bin/postinstall.mjs +32 -0
- package/package.json +2 -1
- package/src/main/server.ts +3 -4
- package/src/renderer/components/settings/sections/PlatformsSection.tsx +22 -3
- package/src/renderer/components/team/TeamDetailView.tsx +13 -1
- package/src/renderer/components/team/TeamListView.tsx +13 -1
package/bin/alias-loader.mjs
CHANGED
|
@@ -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(
|
|
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
|
|
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]
|
|
520
|
+
console.log(`[openHermit] Runtime service already running: ${ccBaseUrl}`);
|
|
521
521
|
} else {
|
|
522
|
-
console.log('[openHermit] Starting bundled
|
|
523
|
-
console.log(`[openHermit]
|
|
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]
|
|
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.
|
|
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",
|
package/src/main/server.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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<
|
|
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 {
|
|
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
|
}
|