jishushell 0.4.17 → 0.4.24-beta.2
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/Dockerfile.hermes-slim +193 -0
- package/apps/hermes-container.yaml +35 -0
- package/apps/ollama-binary.yaml +164 -0
- package/apps/ollama-cpu-container.yaml +37 -0
- package/apps/ollama-with-hollama-binary.yaml +159 -0
- package/apps/openclaw-binary.yaml +69 -0
- package/apps/openclaw-container.yaml +37 -0
- package/apps/openclaw-with-ollama-container.yaml +42 -0
- package/apps/openclaw-with-searxng-container.yaml +136 -0
- package/apps/openwebui-container.yaml +53 -0
- package/apps/playwright-container.yaml +120 -0
- package/apps/searxng-container.yaml +115 -0
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +15 -14
- package/dist/auth.js.map +1 -1
- package/dist/cli/app.d.ts +1 -0
- package/dist/cli/app.js +770 -52
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/backup.d.ts +3 -0
- package/dist/cli/backup.js +434 -0
- package/dist/cli/backup.js.map +1 -0
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.js +61 -35
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/job.d.ts +1 -0
- package/dist/cli/job.js +37 -99
- package/dist/cli/job.js.map +1 -1
- package/dist/cli/llm.d.ts +1 -0
- package/dist/cli/llm.js +20 -14
- package/dist/cli/llm.js.map +1 -1
- package/dist/cli/managed-list.d.ts +30 -0
- package/dist/cli/managed-list.js +129 -0
- package/dist/cli/managed-list.js.map +1 -0
- package/dist/cli/panel.d.ts +4 -3
- package/dist/cli/panel.js +94 -24
- package/dist/cli/panel.js.map +1 -1
- package/dist/cli/version.d.ts +1 -0
- package/dist/cli/version.js +12 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli.js +47 -516
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +68 -0
- package/dist/config.js +266 -12
- package/dist/config.js.map +1 -1
- package/dist/control.d.ts +10 -6
- package/dist/control.js +87 -6
- package/dist/control.js.map +1 -1
- package/dist/install.d.ts +16 -0
- package/dist/install.js +75 -26
- package/dist/install.js.map +1 -1
- package/dist/routes/agent-apps.d.ts +15 -0
- package/dist/routes/agent-apps.js +78 -0
- package/dist/routes/agent-apps.js.map +1 -0
- package/dist/routes/apps.js +186 -7
- package/dist/routes/apps.js.map +1 -1
- package/dist/routes/backup.js +3 -3
- package/dist/routes/backup.js.map +1 -1
- package/dist/routes/instances.d.ts +6 -0
- package/dist/routes/instances.js +862 -879
- package/dist/routes/instances.js.map +1 -1
- package/dist/routes/llm.js +9 -8
- package/dist/routes/llm.js.map +1 -1
- package/dist/routes/runtime.d.ts +15 -0
- package/dist/routes/runtime.js +69 -0
- package/dist/routes/runtime.js.map +1 -0
- package/dist/routes/setup.js +103 -8
- package/dist/routes/setup.js.map +1 -1
- package/dist/routes/system.js +25 -3
- package/dist/routes/system.js.map +1 -1
- package/dist/server.js +71 -7
- package/dist/server.js.map +1 -1
- package/dist/services/agent-apps/catalog.d.ts +30 -0
- package/dist/services/agent-apps/catalog.js +60 -0
- package/dist/services/agent-apps/catalog.js.map +1 -0
- package/dist/services/agent-apps/index.d.ts +36 -0
- package/dist/services/agent-apps/index.js +171 -0
- package/dist/services/agent-apps/index.js.map +1 -0
- package/dist/services/agent-apps/installers/adapter-probes.d.ts +49 -0
- package/dist/services/agent-apps/installers/adapter-probes.js +223 -0
- package/dist/services/agent-apps/installers/adapter-probes.js.map +1 -0
- package/dist/services/agent-apps/installers/adapter.d.ts +30 -0
- package/dist/services/agent-apps/installers/adapter.js +171 -0
- package/dist/services/agent-apps/installers/adapter.js.map +1 -0
- package/dist/services/agent-apps/installers/registry-probe.d.ts +38 -0
- package/dist/services/agent-apps/installers/registry-probe.js +183 -0
- package/dist/services/agent-apps/installers/registry-probe.js.map +1 -0
- package/dist/services/agent-apps/installers/shell-script.d.ts +47 -0
- package/dist/services/agent-apps/installers/shell-script.js +471 -0
- package/dist/services/agent-apps/installers/shell-script.js.map +1 -0
- package/dist/services/agent-apps/types.d.ts +125 -0
- package/dist/services/agent-apps/types.js +17 -0
- package/dist/services/agent-apps/types.js.map +1 -0
- package/dist/services/{app-compiler.d.ts → app/app-compiler.d.ts} +3 -3
- package/dist/services/{app-compiler.js → app/app-compiler.js} +10 -7
- package/dist/services/app/app-compiler.js.map +1 -0
- package/dist/services/app/app-manager.d.ts +142 -0
- package/dist/services/app/app-manager.js +2148 -0
- package/dist/services/app/app-manager.js.map +1 -0
- package/dist/services/app/custom-manager.d.ts +27 -0
- package/dist/services/app/custom-manager.js +285 -0
- package/dist/services/app/custom-manager.js.map +1 -0
- package/dist/services/app/hermes-agent-manager.d.ts +20 -0
- package/dist/services/app/hermes-agent-manager.js +289 -0
- package/dist/services/app/hermes-agent-manager.js.map +1 -0
- package/dist/services/app/id-normalizer.d.ts +27 -0
- package/dist/services/app/id-normalizer.js +77 -0
- package/dist/services/app/id-normalizer.js.map +1 -0
- package/dist/services/app/ollama-manager.d.ts +18 -0
- package/dist/services/app/ollama-manager.js +207 -0
- package/dist/services/app/ollama-manager.js.map +1 -0
- package/dist/services/app/openclaw-manager.d.ts +63 -0
- package/dist/services/app/openclaw-manager.js +1178 -0
- package/dist/services/app/openclaw-manager.js.map +1 -0
- package/dist/services/app/paths.d.ts +47 -0
- package/dist/services/app/paths.js +68 -0
- package/dist/services/app/paths.js.map +1 -0
- package/dist/services/app/registry.d.ts +17 -0
- package/dist/services/app/registry.js +31 -0
- package/dist/services/app/registry.js.map +1 -0
- package/dist/services/app/remote-spec.d.ts +14 -0
- package/dist/services/app/remote-spec.js +58 -0
- package/dist/services/app/remote-spec.js.map +1 -0
- package/dist/services/app/terminal-session-manager.d.ts +27 -0
- package/dist/services/app/terminal-session-manager.js +157 -0
- package/dist/services/app/terminal-session-manager.js.map +1 -0
- package/dist/services/app/types.d.ts +72 -0
- package/dist/services/app/types.js +16 -0
- package/dist/services/app/types.js.map +1 -0
- package/dist/services/backup-manager.js +60 -22
- package/dist/services/backup-manager.js.map +1 -1
- package/dist/services/instance-manager.d.ts +82 -39
- package/dist/services/instance-manager.js +575 -1142
- package/dist/services/instance-manager.js.map +1 -1
- package/dist/services/llm-proxy/circuit-breaker.js +10 -2
- package/dist/services/llm-proxy/circuit-breaker.js.map +1 -1
- package/dist/services/llm-proxy/index.d.ts +14 -1
- package/dist/services/llm-proxy/index.js +51 -6
- package/dist/services/llm-proxy/index.js.map +1 -1
- package/dist/services/nomad-manager.d.ts +260 -3
- package/dist/services/nomad-manager.js +2866 -449
- package/dist/services/nomad-manager.js.map +1 -1
- package/dist/services/panel-manager.d.ts +10 -0
- package/dist/services/panel-manager.js +97 -0
- package/dist/services/panel-manager.js.map +1 -1
- package/dist/services/plugin-installer.js +28 -2
- package/dist/services/plugin-installer.js.map +1 -1
- package/dist/services/process-manager.js +22 -0
- package/dist/services/process-manager.js.map +1 -1
- package/dist/services/runtime/adapters/custom.d.ts +20 -0
- package/dist/services/runtime/adapters/custom.js +90 -0
- package/dist/services/runtime/adapters/custom.js.map +1 -0
- package/dist/services/runtime/adapters/hermes.d.ts +174 -0
- package/dist/services/runtime/adapters/hermes.js +1316 -0
- package/dist/services/runtime/adapters/hermes.js.map +1 -0
- package/dist/services/runtime/adapters/openclaw-routes.d.ts +17 -0
- package/dist/services/runtime/adapters/openclaw-routes.js +946 -0
- package/dist/services/runtime/adapters/openclaw-routes.js.map +1 -0
- package/dist/services/runtime/adapters/openclaw.d.ts +188 -0
- package/dist/services/runtime/adapters/openclaw.js +2195 -0
- package/dist/services/runtime/adapters/openclaw.js.map +1 -0
- package/dist/services/runtime/errors.d.ts +28 -0
- package/dist/services/runtime/errors.js +31 -0
- package/dist/services/runtime/errors.js.map +1 -0
- package/dist/services/runtime/index.d.ts +34 -0
- package/dist/services/runtime/index.js +51 -0
- package/dist/services/runtime/index.js.map +1 -0
- package/dist/services/runtime/instance.d.ts +24 -0
- package/dist/services/runtime/instance.js +143 -0
- package/dist/services/runtime/instance.js.map +1 -0
- package/dist/services/runtime/migrations.d.ts +15 -0
- package/dist/services/runtime/migrations.js +25 -0
- package/dist/services/runtime/migrations.js.map +1 -0
- package/dist/services/runtime/registry.d.ts +13 -0
- package/dist/services/runtime/registry.js +32 -0
- package/dist/services/runtime/registry.js.map +1 -0
- package/dist/services/runtime/types.d.ts +545 -0
- package/dist/services/runtime/types.js +14 -0
- package/dist/services/runtime/types.js.map +1 -0
- package/dist/services/setup-manager.d.ts +70 -29
- package/dist/services/setup-manager.js +278 -597
- package/dist/services/setup-manager.js.map +1 -1
- package/dist/services/task-registry.d.ts +44 -0
- package/dist/services/task-registry.js +74 -0
- package/dist/services/task-registry.js.map +1 -0
- package/dist/services/telemetry/heartbeat.d.ts +6 -6
- package/dist/services/telemetry/heartbeat.js +29 -30
- package/dist/services/telemetry/heartbeat.js.map +1 -1
- package/dist/types.d.ts +164 -2
- package/dist/utils/docker-host.d.ts +15 -0
- package/dist/utils/docker-host.js +64 -0
- package/dist/utils/docker-host.js.map +1 -0
- package/install/jishu-install.sh +25 -2
- package/package.json +14 -4
- package/public/assets/Dashboard-rh9qpYRR.js +1 -0
- package/public/assets/HermesChatPanel-D6JI6lLY.js +1 -0
- package/public/assets/HermesConfigForm-DcbSemaj.js +4 -0
- package/public/assets/InitPassword-CFTKsED4.js +1 -0
- package/public/assets/InstanceDetail-BhNIKA6Z.js +91 -0
- package/public/assets/{Login-D1Bt-Lyk.js → Login-KB9qrtM0.js} +1 -1
- package/public/assets/NewInstance-CxkO8Hlq.js +1 -0
- package/public/assets/Settings-BVWJvOkU.js +1 -0
- package/public/assets/Setup-X-lzuaUT.js +1 -0
- package/public/assets/WeixinLoginPanel-gca0QTic.js +9 -0
- package/public/assets/index-C8B0cFJM.js +19 -0
- package/public/assets/index-CPhVFEsx.css +1 -0
- package/public/assets/input-paste-CrNVAyOy.js +1 -0
- package/public/assets/registry-fVUSujib.js +2 -0
- package/public/assets/{usePolling-CK0DfI4h.js → usePolling-Do5Erqm_.js} +1 -1
- package/public/assets/vendor-i18n-ucpM0OR0.js +9 -0
- package/public/assets/{vendor-react-B1-3Yrt-.js → vendor-react-Bk1hRGiY.js} +1 -1
- package/public/favicon.png +0 -0
- package/public/index.html +9 -4
- package/public/logos/hermes.png +0 -0
- package/public/logos/ollama.png +0 -0
- package/public/logos/openclaw.svg +60 -0
- package/scripts/build-hermes-image.sh +21 -0
- package/scripts/build-local.sh +54 -0
- package/scripts/check-adapter-isolation.ts +293 -0
- package/scripts/fixtures/instances/hermes-sample/instance.json +37 -0
- package/scripts/fixtures/instances/legacy-openclaw-sample/instance.json +7 -0
- package/scripts/smoke/hermes-bootstrap.sh +195 -0
- package/templates/hermes-entrypoint.sh +154 -0
- package/dist/cli/openclaw.d.ts +0 -12
- package/dist/cli/openclaw.js +0 -156
- package/dist/cli/openclaw.js.map +0 -1
- package/dist/services/app-compiler.js.map +0 -1
- package/dist/services/app-manager.d.ts +0 -17
- package/dist/services/app-manager.js +0 -168
- package/dist/services/app-manager.js.map +0 -1
- package/dist/services/job-manager.d.ts +0 -22
- package/dist/services/job-manager.js +0 -102
- package/dist/services/job-manager.js.map +0 -1
- package/public/assets/Dashboard-CQsp1Mr9.js +0 -1
- package/public/assets/InitPassword-BEC8SE4A.js +0 -1
- package/public/assets/InstanceDetail-B5wTgNEg.js +0 -17
- package/public/assets/NewInstance-GQzm3K9D.js +0 -1
- package/public/assets/Settings-ByjGlqhP.js +0 -1
- package/public/assets/Setup-cMF21Y-8.js +0 -1
- package/public/assets/index-B6qQP4mH.css +0 -1
- package/public/assets/index-BuTQtuNy.js +0 -16
- package/public/assets/vendor-i18n-CfW0RvgE.js +0 -9
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installer strategy for adapter-backed agent apps (hermes, openclaw).
|
|
3
|
+
*
|
|
4
|
+
* Delegates install to `adapter.startBuildRuntimeImage` (preferred when
|
|
5
|
+
* present — openclaw builds its image locally) or
|
|
6
|
+
* `adapter.startInstallRuntime` (hermes pulls from GHCR). Uninstall runs
|
|
7
|
+
* locally here (docker image rm + clear runtime_catalog + drop shim).
|
|
8
|
+
*
|
|
9
|
+
* Probe + cache logic lives in `adapter-probes.ts`; this file re-exports
|
|
10
|
+
* the probes so callers import one entry point.
|
|
11
|
+
*/
|
|
12
|
+
import { execFile } from "child_process";
|
|
13
|
+
import { existsSync, rmSync } from "fs";
|
|
14
|
+
import { promisify } from "util";
|
|
15
|
+
import { HERMES_RUNTIME_DIR, getPanelConfig, savePanelConfig, } from "../../../config.js";
|
|
16
|
+
import { listInstances } from "../../app/app-manager.js";
|
|
17
|
+
import { getAdapter, hasAdapter, resolveAgentType } from "../../runtime/index.js";
|
|
18
|
+
import { createTask, emitTask, getRunningTasks, } from "../../task-registry.js";
|
|
19
|
+
import { resolveAdapterImage } from "./adapter-probes.js";
|
|
20
|
+
const execFileAsync = promisify(execFile);
|
|
21
|
+
export { forceRefreshAllAdapterUpdates, getUpdateCacheLastCheckedAt, probeAdapterImageSizeMB, probeAdapterStatus, probeAdapterUpdateAvailable, resolveAdapterImage, } from "./adapter-probes.js";
|
|
22
|
+
// ── Dispatch: install ───────────────────────────────────────────────────
|
|
23
|
+
export async function startAdapterInstall(agentType, options = {}) {
|
|
24
|
+
if (!hasAdapter(agentType)) {
|
|
25
|
+
return { ok: false, error: `Unknown agentType "${agentType}"` };
|
|
26
|
+
}
|
|
27
|
+
// Reject install while uninstall is running — they are destructive of
|
|
28
|
+
// each other. Names are disjoint (`uninstall-${agentType}` vs
|
|
29
|
+
// `${agentType}` / `${agentType}-*`), so this check can't match an
|
|
30
|
+
// install task.
|
|
31
|
+
if (getRunningTasks(`uninstall-${agentType}`).length > 0) {
|
|
32
|
+
return {
|
|
33
|
+
ok: false,
|
|
34
|
+
error: `${agentType} 正在卸载,请等待卸载完成后再安装`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Dedup: if a task for this agent is already running (Setup wizard, or
|
|
38
|
+
// the user clicked install twice), join it instead of starting a second.
|
|
39
|
+
// Adapters use prefix-based names (`openclaw`, `openclaw-docker-pull`,
|
|
40
|
+
// `hermes`), so a prefix match matches install variants but — by design
|
|
41
|
+
// — cannot match `uninstall-${agentType}`.
|
|
42
|
+
const existing = getRunningTasks(agentType);
|
|
43
|
+
if (existing.length > 0) {
|
|
44
|
+
return {
|
|
45
|
+
ok: true,
|
|
46
|
+
taskId: existing[0].id,
|
|
47
|
+
reused: true,
|
|
48
|
+
message: `${agentType} install already in progress`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const adapter = getAdapter(agentType);
|
|
52
|
+
let result;
|
|
53
|
+
if (typeof adapter.startBuildRuntimeImage === "function") {
|
|
54
|
+
result = await adapter.startBuildRuntimeImage(options);
|
|
55
|
+
}
|
|
56
|
+
else if (typeof adapter.startInstallRuntime === "function") {
|
|
57
|
+
result = adapter.startInstallRuntime(options);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return { ok: false, error: `Runtime "${agentType}" does not implement install` };
|
|
61
|
+
}
|
|
62
|
+
if (result && typeof result === "object") {
|
|
63
|
+
return {
|
|
64
|
+
ok: result.ok !== false,
|
|
65
|
+
taskId: result.taskId,
|
|
66
|
+
message: result.message,
|
|
67
|
+
error: result.ok === false ? (result.error || result.message) : undefined,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { ok: false, error: "Adapter returned an unexpected install result" };
|
|
71
|
+
}
|
|
72
|
+
// ── Dispatch: uninstall ─────────────────────────────────────────────────
|
|
73
|
+
export function startAdapterUninstall(agentType) {
|
|
74
|
+
if (!hasAdapter(agentType)) {
|
|
75
|
+
return { ok: false, error: `Unknown agentType "${agentType}"` };
|
|
76
|
+
}
|
|
77
|
+
// Reject uninstall while install/update is in flight — we don't want to
|
|
78
|
+
// yank the docker image out from under a running docker pull.
|
|
79
|
+
if (getRunningTasks(agentType).length > 0) {
|
|
80
|
+
return {
|
|
81
|
+
ok: false,
|
|
82
|
+
error: `${agentType} 正在安装/更新,请等待完成后再卸载`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Uninstall dedup: second uninstall clicks within the window join nothing
|
|
86
|
+
// — we just tell the user it's already running.
|
|
87
|
+
if (getRunningTasks(`uninstall-${agentType}`).length > 0) {
|
|
88
|
+
return {
|
|
89
|
+
ok: false,
|
|
90
|
+
error: `${agentType} 卸载已在进行中`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const image = resolveAdapterImage(agentType);
|
|
94
|
+
const task = createTask(`uninstall-${agentType}`);
|
|
95
|
+
(async () => {
|
|
96
|
+
try {
|
|
97
|
+
emitTask(task, { type: "progress", message: `准备卸载 ${agentType}...`, progress: 0 });
|
|
98
|
+
if (image) {
|
|
99
|
+
emitTask(task, { type: "progress", message: `删除 docker 镜像: ${image}`, progress: 30 });
|
|
100
|
+
try {
|
|
101
|
+
await execFileAsync("docker", ["image", "rm", "-f", image], {
|
|
102
|
+
timeout: 30_000, encoding: "utf-8",
|
|
103
|
+
});
|
|
104
|
+
emitTask(task, { type: "log", message: "docker image rm 成功" });
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
emitTask(task, {
|
|
108
|
+
type: "log",
|
|
109
|
+
message: `docker image rm 失败(可能镜像不存在): ${e.message || e}`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
emitTask(task, { type: "log", message: "未找到镜像引用,跳过 docker image rm" });
|
|
115
|
+
}
|
|
116
|
+
emitTask(task, { type: "progress", message: "清理 runtime_catalog...", progress: 70 });
|
|
117
|
+
const config = getPanelConfig();
|
|
118
|
+
if (config.runtime_catalog && typeof config.runtime_catalog === "object") {
|
|
119
|
+
delete config.runtime_catalog[agentType];
|
|
120
|
+
savePanelConfig(config);
|
|
121
|
+
}
|
|
122
|
+
if (agentType === "hermes") {
|
|
123
|
+
emitTask(task, { type: "progress", message: "清理 Hermes shim 目录...", progress: 85 });
|
|
124
|
+
try {
|
|
125
|
+
if (existsSync(HERMES_RUNTIME_DIR)) {
|
|
126
|
+
rmSync(HERMES_RUNTIME_DIR, { recursive: true, force: true });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
emitTask(task, { type: "log", message: `shim 目录清理失败: ${e.message || e}` });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
emitTask(task, { type: "done", message: `${agentType} 卸载完成`, progress: 100 });
|
|
134
|
+
task.status = "done";
|
|
135
|
+
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
emitTask(task, { type: "error", message: `卸载失败: ${e?.message || e}` });
|
|
138
|
+
task.status = "error";
|
|
139
|
+
}
|
|
140
|
+
})();
|
|
141
|
+
return { ok: true, taskId: task.id };
|
|
142
|
+
}
|
|
143
|
+
// ── Helpers consumed by routes/index layer ──────────────────────────────
|
|
144
|
+
/**
|
|
145
|
+
* Current running task for this agentType. Returns both the id and the
|
|
146
|
+
* kind so the UI can render "安装中" vs "卸载中" from one field instead
|
|
147
|
+
* of having to guess from task name shape.
|
|
148
|
+
*
|
|
149
|
+
* Install tasks match by prefix (`openclaw`, `openclaw-docker-pull`,
|
|
150
|
+
* `hermes`). Uninstall tasks use the disjoint `uninstall-${agentType}`
|
|
151
|
+
* name so no prefix collision is possible.
|
|
152
|
+
*/
|
|
153
|
+
export function findRunningAdapterTask(agentType) {
|
|
154
|
+
const install = getRunningTasks(agentType)[0];
|
|
155
|
+
if (install)
|
|
156
|
+
return { id: install.id, kind: "install" };
|
|
157
|
+
const uninstall = getRunningTasks(`uninstall-${agentType}`)[0];
|
|
158
|
+
if (uninstall)
|
|
159
|
+
return { id: uninstall.id, kind: "uninstall" };
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
/** Count live instances bound to this agentType — used to block uninstall. */
|
|
163
|
+
export function countInstancesUsingAgentType(agentType) {
|
|
164
|
+
let count = 0;
|
|
165
|
+
for (const meta of listInstances()) {
|
|
166
|
+
if (resolveAgentType(meta) === agentType)
|
|
167
|
+
count += 1;
|
|
168
|
+
}
|
|
169
|
+
return count;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../../src/services/agent-apps/installers/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OCI / Docker Registry v2 digest lookups via curl.
|
|
3
|
+
*
|
|
4
|
+
* We shell out to curl instead of using Node's built-in `fetch` because:
|
|
5
|
+
* - Node's fetch (undici) ships a 10 s TCP connect timeout that isn't
|
|
6
|
+
* configurable without pulling undici in as a direct dep, and the TLS
|
|
7
|
+
* handshake to ghcr.io from edge devices on slow international links
|
|
8
|
+
* routinely exceeds that (9–15 s measured from a Pi in mainland China).
|
|
9
|
+
* - curl's `--max-time` is wall-clock and reliable.
|
|
10
|
+
* - curl is already present on every target platform.
|
|
11
|
+
*
|
|
12
|
+
* The call chain implements the standard OCI distribution bearer-token flow:
|
|
13
|
+
* 1. GET <realm>?service=...&scope=... → bearer token
|
|
14
|
+
* 2. HEAD /v2/<repository>/manifests/<reference> → docker-content-digest
|
|
15
|
+
*
|
|
16
|
+
* Well-known public registries (GHCR, Docker Hub, Quay) always require a
|
|
17
|
+
* token, so we skip the throwaway unauthenticated probe for them — that
|
|
18
|
+
* alone saves ~10 s per image on slow WAN links.
|
|
19
|
+
*/
|
|
20
|
+
export interface ImageRef {
|
|
21
|
+
registry: string;
|
|
22
|
+
repository: string;
|
|
23
|
+
reference: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse a docker image reference into `{ registry, repository, reference }`.
|
|
27
|
+
* Handles: "ghcr.io/owner/name:tag", "owner/name:tag" (defaults to Docker
|
|
28
|
+
* Hub), "name" (defaults to "library/<name>:latest"). Returns null for
|
|
29
|
+
* digest-pinned refs (no lookup is needed) or malformed strings.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseImageRef(image: string): ImageRef | null;
|
|
32
|
+
/**
|
|
33
|
+
* Fetch the current remote digest (sha256 hex, without the "sha256:" prefix)
|
|
34
|
+
* for a fully-resolved image reference. Returns null when the registry is
|
|
35
|
+
* unreachable, the image is private without an auth token we can obtain, or
|
|
36
|
+
* any other probe failure.
|
|
37
|
+
*/
|
|
38
|
+
export declare function fetchRemoteDigest(ref: ImageRef): Promise<string | null>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OCI / Docker Registry v2 digest lookups via curl.
|
|
3
|
+
*
|
|
4
|
+
* We shell out to curl instead of using Node's built-in `fetch` because:
|
|
5
|
+
* - Node's fetch (undici) ships a 10 s TCP connect timeout that isn't
|
|
6
|
+
* configurable without pulling undici in as a direct dep, and the TLS
|
|
7
|
+
* handshake to ghcr.io from edge devices on slow international links
|
|
8
|
+
* routinely exceeds that (9–15 s measured from a Pi in mainland China).
|
|
9
|
+
* - curl's `--max-time` is wall-clock and reliable.
|
|
10
|
+
* - curl is already present on every target platform.
|
|
11
|
+
*
|
|
12
|
+
* The call chain implements the standard OCI distribution bearer-token flow:
|
|
13
|
+
* 1. GET <realm>?service=...&scope=... → bearer token
|
|
14
|
+
* 2. HEAD /v2/<repository>/manifests/<reference> → docker-content-digest
|
|
15
|
+
*
|
|
16
|
+
* Well-known public registries (GHCR, Docker Hub, Quay) always require a
|
|
17
|
+
* token, so we skip the throwaway unauthenticated probe for them — that
|
|
18
|
+
* alone saves ~10 s per image on slow WAN links.
|
|
19
|
+
*/
|
|
20
|
+
import { execFile } from "child_process";
|
|
21
|
+
import { promisify } from "util";
|
|
22
|
+
const execFileAsync = promisify(execFile);
|
|
23
|
+
const KNOWN_BEARER_REGISTRIES = new Set([
|
|
24
|
+
"ghcr.io",
|
|
25
|
+
"registry-1.docker.io",
|
|
26
|
+
"docker.io",
|
|
27
|
+
"quay.io",
|
|
28
|
+
]);
|
|
29
|
+
/** Accept header covering all manifest / index media types. */
|
|
30
|
+
const MANIFEST_ACCEPT = [
|
|
31
|
+
"application/vnd.oci.image.index.v1+json",
|
|
32
|
+
"application/vnd.oci.image.manifest.v1+json",
|
|
33
|
+
"application/vnd.docker.distribution.manifest.list.v2+json",
|
|
34
|
+
"application/vnd.docker.distribution.manifest.v2+json",
|
|
35
|
+
].join(", ");
|
|
36
|
+
/**
|
|
37
|
+
* Parse a docker image reference into `{ registry, repository, reference }`.
|
|
38
|
+
* Handles: "ghcr.io/owner/name:tag", "owner/name:tag" (defaults to Docker
|
|
39
|
+
* Hub), "name" (defaults to "library/<name>:latest"). Returns null for
|
|
40
|
+
* digest-pinned refs (no lookup is needed) or malformed strings.
|
|
41
|
+
*/
|
|
42
|
+
export function parseImageRef(image) {
|
|
43
|
+
if (image.includes("@"))
|
|
44
|
+
return null;
|
|
45
|
+
const trimmed = image.trim();
|
|
46
|
+
if (!trimmed)
|
|
47
|
+
return null;
|
|
48
|
+
const firstSlash = trimmed.indexOf("/");
|
|
49
|
+
const firstSegment = firstSlash === -1 ? "" : trimmed.slice(0, firstSlash);
|
|
50
|
+
const hasRegistry = firstSegment.includes(".") ||
|
|
51
|
+
firstSegment.includes(":") ||
|
|
52
|
+
firstSegment === "localhost";
|
|
53
|
+
let registry;
|
|
54
|
+
let rest;
|
|
55
|
+
if (hasRegistry) {
|
|
56
|
+
registry = firstSegment;
|
|
57
|
+
rest = trimmed.slice(firstSlash + 1);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
registry = "registry-1.docker.io";
|
|
61
|
+
rest = trimmed.includes("/") ? trimmed : `library/${trimmed}`;
|
|
62
|
+
}
|
|
63
|
+
const colon = rest.lastIndexOf(":");
|
|
64
|
+
let repository;
|
|
65
|
+
let reference;
|
|
66
|
+
if (colon === -1 || rest.indexOf("/", colon) !== -1) {
|
|
67
|
+
repository = rest;
|
|
68
|
+
reference = "latest";
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
repository = rest.slice(0, colon);
|
|
72
|
+
reference = rest.slice(colon + 1);
|
|
73
|
+
}
|
|
74
|
+
if (!/^[a-z0-9][a-z0-9._\-/]{0,254}$/.test(repository))
|
|
75
|
+
return null;
|
|
76
|
+
if (!/^[A-Za-z0-9._\-]{1,128}$/.test(reference))
|
|
77
|
+
return null;
|
|
78
|
+
return { registry, repository, reference };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Fetch the current remote digest (sha256 hex, without the "sha256:" prefix)
|
|
82
|
+
* for a fully-resolved image reference. Returns null when the registry is
|
|
83
|
+
* unreachable, the image is private without an auth token we can obtain, or
|
|
84
|
+
* any other probe failure.
|
|
85
|
+
*/
|
|
86
|
+
export async function fetchRemoteDigest(ref) {
|
|
87
|
+
const manifestUrl = `https://${ref.registry}/v2/${ref.repository}/manifests/${ref.reference}`;
|
|
88
|
+
if (KNOWN_BEARER_REGISTRIES.has(ref.registry)) {
|
|
89
|
+
const token = await fetchBearerToken(`https://${ref.registry}/token`, ref.registry, `repository:${ref.repository}:pull`);
|
|
90
|
+
if (!token)
|
|
91
|
+
return null;
|
|
92
|
+
return headDigestWithAuth(manifestUrl, token);
|
|
93
|
+
}
|
|
94
|
+
// Unknown registry: try unauthenticated first, then follow the challenge.
|
|
95
|
+
const unauth = await curlHead(manifestUrl, { Accept: MANIFEST_ACCEPT });
|
|
96
|
+
if (unauth.ok) {
|
|
97
|
+
const d = extractDigest(unauth.headers);
|
|
98
|
+
if (d)
|
|
99
|
+
return d;
|
|
100
|
+
}
|
|
101
|
+
const challenge = unauth.headers["www-authenticate"] || "";
|
|
102
|
+
const parsed = parseBearerChallenge(challenge);
|
|
103
|
+
if (!parsed)
|
|
104
|
+
return null;
|
|
105
|
+
const token = await fetchBearerToken(parsed.realm, parsed.service || "", parsed.scope || `repository:${ref.repository}:pull`);
|
|
106
|
+
if (!token)
|
|
107
|
+
return null;
|
|
108
|
+
return headDigestWithAuth(manifestUrl, token);
|
|
109
|
+
}
|
|
110
|
+
async function headDigestWithAuth(manifestUrl, token) {
|
|
111
|
+
const resp = await curlHead(manifestUrl, {
|
|
112
|
+
Accept: MANIFEST_ACCEPT,
|
|
113
|
+
Authorization: `Bearer ${token}`,
|
|
114
|
+
});
|
|
115
|
+
return resp.ok ? extractDigest(resp.headers) : null;
|
|
116
|
+
}
|
|
117
|
+
async function fetchBearerToken(realm, service, scope) {
|
|
118
|
+
const url = new URL(realm);
|
|
119
|
+
url.searchParams.set("service", service);
|
|
120
|
+
url.searchParams.set("scope", scope);
|
|
121
|
+
try {
|
|
122
|
+
const { stdout } = await execFileAsync("curl", [
|
|
123
|
+
"--silent", "--fail-with-body", "--show-error",
|
|
124
|
+
"--max-time", "20",
|
|
125
|
+
url.toString(),
|
|
126
|
+
], { timeout: 25_000, encoding: "utf-8" });
|
|
127
|
+
const body = JSON.parse(stdout);
|
|
128
|
+
return body.token || body.access_token || null;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function curlHead(url, headers) {
|
|
135
|
+
const args = [
|
|
136
|
+
"--silent", "--show-error", "--head",
|
|
137
|
+
"--max-time", "20",
|
|
138
|
+
"--write-out", "\n__STATUS__%{http_code}\n",
|
|
139
|
+
];
|
|
140
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
141
|
+
args.push("-H", `${k}: ${v}`);
|
|
142
|
+
}
|
|
143
|
+
args.push(url);
|
|
144
|
+
try {
|
|
145
|
+
const { stdout } = await execFileAsync("curl", args, {
|
|
146
|
+
timeout: 25_000,
|
|
147
|
+
encoding: "utf-8",
|
|
148
|
+
maxBuffer: 1 * 1024 * 1024,
|
|
149
|
+
});
|
|
150
|
+
const statusMatch = stdout.match(/__STATUS__(\d{3})/);
|
|
151
|
+
const statusCode = statusMatch ? parseInt(statusMatch[1], 10) : 0;
|
|
152
|
+
const parsed = {};
|
|
153
|
+
for (const raw of stdout.split(/\r?\n/)) {
|
|
154
|
+
if (!raw || raw.startsWith("HTTP/") || raw.startsWith("__STATUS__"))
|
|
155
|
+
continue;
|
|
156
|
+
const idx = raw.indexOf(":");
|
|
157
|
+
if (idx > 0) {
|
|
158
|
+
parsed[raw.slice(0, idx).trim().toLowerCase()] = raw.slice(idx + 1).trim();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { ok: statusCode >= 200 && statusCode < 400, statusCode, headers: parsed };
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return { ok: false, statusCode: 0, headers: {} };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function extractDigest(headers) {
|
|
168
|
+
const m = headers["docker-content-digest"]?.match(/^sha256:([a-f0-9]{64})$/);
|
|
169
|
+
return m ? m[1] : null;
|
|
170
|
+
}
|
|
171
|
+
function parseBearerChallenge(header) {
|
|
172
|
+
if (!/^\s*Bearer\b/i.test(header))
|
|
173
|
+
return null;
|
|
174
|
+
const realm = /realm="([^"]+)"/i.exec(header)?.[1];
|
|
175
|
+
if (!realm)
|
|
176
|
+
return null;
|
|
177
|
+
return {
|
|
178
|
+
realm,
|
|
179
|
+
service: /service="([^"]+)"/i.exec(header)?.[1],
|
|
180
|
+
scope: /scope="([^"]+)"/i.exec(header)?.[1],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=registry-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-probe.js","sourceRoot":"","sources":["../../../../src/services/agent-apps/installers/registry-probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installer strategy for shell-script-driven agent apps (Ollama and any other
|
|
3
|
+
* system tool shipped as a `curl | bash` installer).
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - probe installed version + binary size via `probeCommand`
|
|
7
|
+
* - probe update availability via GitHub Releases (when `githubRepo` set)
|
|
8
|
+
* - install: fetch script → optional sha256 verify → `sudo -n bash`
|
|
9
|
+
* - uninstall: stop+disable systemd unit + rm binary + rm extraCleanup
|
|
10
|
+
*
|
|
11
|
+
* Heavy ops stream progress through the shared task-registry so the UI
|
|
12
|
+
* picks them up via `/api/setup/tasks/:id`, identical to adapter installs.
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentAppSource, InstallStartResult } from "../types.js";
|
|
15
|
+
type ShellScriptSource = Extract<AgentAppSource, {
|
|
16
|
+
kind: "shell-script";
|
|
17
|
+
}>;
|
|
18
|
+
export declare function probeShellScriptStatus(source: ShellScriptSource): Promise<{
|
|
19
|
+
installed: boolean;
|
|
20
|
+
version?: string;
|
|
21
|
+
} | null>;
|
|
22
|
+
export declare function probeShellScriptSizeMB(source: ShellScriptSource): Promise<number | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Read-only cache lookup used by `buildCardView`. Returns null (UI stays
|
|
25
|
+
* neutral) until the user clicks "检查更新" at least once, which kicks off
|
|
26
|
+
* the network probe via `refreshShellScriptUpdateCache`.
|
|
27
|
+
*
|
|
28
|
+
* Intentionally NOT falling back to an on-demand probe here — the catalog
|
|
29
|
+
* endpoint is polled every 5 s and the GitHub Releases API is slow + rate-
|
|
30
|
+
* limited. See docs/agent-apps-design.md "update checks only on explicit
|
|
31
|
+
* click".
|
|
32
|
+
*/
|
|
33
|
+
export declare function readShellScriptUpdateAvailable(appId: string): boolean | null;
|
|
34
|
+
export declare function getShellScriptUpdateCacheLastCheckedAt(): number | null;
|
|
35
|
+
/**
|
|
36
|
+
* Compare installed version vs GitHub Releases latest tag. Writes the
|
|
37
|
+
* result to the cache and returns it. Called by `checkAllAgentAppUpdates`;
|
|
38
|
+
* not called from the catalog hot path.
|
|
39
|
+
*/
|
|
40
|
+
export declare function refreshShellScriptUpdateCache(appId: string, source: ShellScriptSource): Promise<boolean | null>;
|
|
41
|
+
export declare function findRunningShellScriptTask(appId: string): {
|
|
42
|
+
id: string;
|
|
43
|
+
kind: "install" | "uninstall";
|
|
44
|
+
} | undefined;
|
|
45
|
+
export declare function startShellScriptInstall(appId: string, source: ShellScriptSource): Promise<InstallStartResult>;
|
|
46
|
+
export declare function startShellScriptUninstall(appId: string, source: ShellScriptSource): Promise<InstallStartResult>;
|
|
47
|
+
export {};
|