jishushell 0.4.30 → 0.5.15
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/apps/anythingllm-container.yaml +287 -0
- package/apps/browserless-chromium-container.yaml +18 -6
- package/apps/filebrowser-container.yaml +163 -0
- package/apps/openclaw-binary.yaml +8 -0
- package/apps/openclaw-container.yaml +9 -1
- package/apps/openclaw-with-searxng-container.yaml +4 -0
- package/apps/searxng-container.yaml +5 -4
- package/apps/weknora-container.yaml +471 -0
- package/dist/cli/panel.js.map +1 -1
- package/dist/config.d.ts +19 -0
- package/dist/config.js +99 -1
- package/dist/config.js.map +1 -1
- package/dist/install.js +3 -3
- package/dist/install.js.map +1 -1
- package/dist/routes/auth.js +2 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/backup.js +64 -11
- package/dist/routes/backup.js.map +1 -1
- package/dist/routes/external-mounts.d.ts +17 -0
- package/dist/routes/external-mounts.js +73 -0
- package/dist/routes/external-mounts.js.map +1 -0
- package/dist/routes/file-mounts.d.ts +13 -0
- package/dist/routes/file-mounts.js +90 -0
- package/dist/routes/file-mounts.js.map +1 -0
- package/dist/routes/files-organize.d.ts +28 -0
- package/dist/routes/files-organize.js +167 -0
- package/dist/routes/files-organize.js.map +1 -0
- package/dist/routes/files.d.ts +31 -0
- package/dist/routes/files.js +321 -0
- package/dist/routes/files.js.map +1 -0
- package/dist/routes/instances.js +45 -7
- package/dist/routes/instances.js.map +1 -1
- package/dist/routes/internal.d.ts +2 -0
- package/dist/routes/internal.js +59 -0
- package/dist/routes/internal.js.map +1 -0
- package/dist/routes/setup.js +9 -9
- package/dist/routes/setup.js.map +1 -1
- package/dist/routes/system.js +1 -1
- package/dist/routes/system.js.map +1 -1
- package/dist/routes/webdav.d.ts +17 -0
- package/dist/routes/webdav.js +114 -0
- package/dist/routes/webdav.js.map +1 -0
- package/dist/server.js +341 -3
- package/dist/server.js.map +1 -1
- package/dist/services/app/app-compiler.d.ts +1 -1
- package/dist/services/app/app-compiler.js +5 -5
- package/dist/services/app/app-compiler.js.map +1 -1
- package/dist/services/app/app-manager.d.ts +1 -0
- package/dist/services/app/app-manager.js +172 -41
- package/dist/services/app/app-manager.js.map +1 -1
- package/dist/services/app/custom-manager.js.map +1 -1
- package/dist/services/app/hermes-agent-manager.js +1 -0
- package/dist/services/app/hermes-agent-manager.js.map +1 -1
- package/dist/services/app/ollama-manager.js +1 -1
- package/dist/services/app/ollama-manager.js.map +1 -1
- package/dist/services/app/openclaw-manager.js +20 -3
- package/dist/services/app/openclaw-manager.js.map +1 -1
- package/dist/services/app/platform-transform.d.ts +32 -0
- package/dist/services/app/platform-transform.js +65 -0
- package/dist/services/app/platform-transform.js.map +1 -0
- package/dist/services/app-passwords.d.ts +61 -0
- package/dist/services/app-passwords.js +173 -0
- package/dist/services/app-passwords.js.map +1 -0
- package/dist/services/backup-manager.d.ts +11 -0
- package/dist/services/backup-manager.js +177 -4
- package/dist/services/backup-manager.js.map +1 -1
- package/dist/services/connection-apply.d.ts +2 -0
- package/dist/services/connection-apply.js +55 -1
- package/dist/services/connection-apply.js.map +1 -1
- package/dist/services/connection-resolver.js +1 -1
- package/dist/services/connection-resolver.js.map +1 -1
- package/dist/services/connection-transactor.d.ts +2 -0
- package/dist/services/connection-transactor.js +12 -2
- package/dist/services/connection-transactor.js.map +1 -1
- package/dist/services/external-mounts.d.ts +40 -0
- package/dist/services/external-mounts.js +187 -0
- package/dist/services/external-mounts.js.map +1 -0
- package/dist/services/files-manager.d.ts +252 -0
- package/dist/services/files-manager.js +1075 -0
- package/dist/services/files-manager.js.map +1 -0
- package/dist/services/files-mounts.d.ts +42 -0
- package/dist/services/files-mounts.js +207 -0
- package/dist/services/files-mounts.js.map +1 -0
- package/dist/services/instance-manager.js +1 -23
- package/dist/services/instance-manager.js.map +1 -1
- package/dist/services/llm-proxy/index.js.map +1 -1
- package/dist/services/llm-proxy/ssrf.js +6 -2
- package/dist/services/llm-proxy/ssrf.js.map +1 -1
- package/dist/services/nomad-manager.d.ts +4 -0
- package/dist/services/nomad-manager.js +53 -19
- package/dist/services/nomad-manager.js.map +1 -1
- package/dist/services/organize/applier.d.ts +46 -0
- package/dist/services/organize/applier.js +218 -0
- package/dist/services/organize/applier.js.map +1 -0
- package/dist/services/organize/rules.d.ts +57 -0
- package/dist/services/organize/rules.js +286 -0
- package/dist/services/organize/rules.js.map +1 -0
- package/dist/services/organize/scanner.d.ts +50 -0
- package/dist/services/organize/scanner.js +366 -0
- package/dist/services/organize/scanner.js.map +1 -0
- package/dist/services/organize/store.d.ts +14 -0
- package/dist/services/organize/store.js +82 -0
- package/dist/services/organize/store.js.map +1 -0
- package/dist/services/panel-manager.js +20 -1
- package/dist/services/panel-manager.js.map +1 -1
- package/dist/services/process-manager.js +3 -2
- package/dist/services/process-manager.js.map +1 -1
- package/dist/services/runtime/adapters/hermes.js +1 -1
- package/dist/services/runtime/adapters/hermes.js.map +1 -1
- package/dist/services/runtime/adapters/openclaw-routes.d.ts +8 -2
- package/dist/services/runtime/adapters/openclaw-routes.js +68 -0
- package/dist/services/runtime/adapters/openclaw-routes.js.map +1 -1
- package/dist/services/runtime/adapters/openclaw.d.ts +90 -0
- package/dist/services/runtime/adapters/openclaw.js +957 -45
- package/dist/services/runtime/adapters/openclaw.js.map +1 -1
- package/dist/services/runtime/instance.d.ts +1 -1
- package/dist/services/runtime/instance.js +1 -1
- package/dist/services/runtime/instance.js.map +1 -1
- package/dist/services/runtime/mcp-shims/anythingllm-shim.d.ts +46 -0
- package/dist/services/runtime/mcp-shims/anythingllm-shim.js +281 -0
- package/dist/services/runtime/mcp-shims/anythingllm-shim.js.map +1 -0
- package/dist/services/runtime/mcp-shims/drive-shim.d.ts +54 -0
- package/dist/services/runtime/mcp-shims/drive-shim.js +489 -0
- package/dist/services/runtime/mcp-shims/drive-shim.js.map +1 -0
- package/dist/services/runtime/types.d.ts +31 -0
- package/dist/services/setup-manager.js +93 -18
- package/dist/services/setup-manager.js.map +1 -1
- package/dist/services/suggestions.js.map +1 -1
- package/dist/services/webdav/server.d.ts +24 -0
- package/dist/services/webdav/server.js +420 -0
- package/dist/services/webdav/server.js.map +1 -0
- package/dist/services/webdav/xml-builder.d.ts +73 -0
- package/dist/services/webdav/xml-builder.js +156 -0
- package/dist/services/webdav/xml-builder.js.map +1 -0
- package/dist/services/workspace-builder.d.ts +29 -0
- package/dist/services/workspace-builder.js +188 -0
- package/dist/services/workspace-builder.js.map +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/utils/path-locks.d.ts +30 -0
- package/dist/utils/path-locks.js +63 -0
- package/dist/utils/path-locks.js.map +1 -0
- package/dist/utils/path-safety.d.ts +41 -0
- package/dist/utils/path-safety.js +119 -0
- package/dist/utils/path-safety.js.map +1 -0
- package/dist/utils/safe-write.d.ts +24 -0
- package/dist/utils/safe-write.js +82 -0
- package/dist/utils/safe-write.js.map +1 -0
- package/package.json +16 -1
- package/public/assets/Dashboard-BdWPtroF.js +1 -0
- package/public/assets/{HermesChatPanel-_GHoklgo.js → HermesChatPanel-B_2HlVBQ.js} +1 -1
- package/public/assets/{HermesConfigForm-anDnwUp_.js → HermesConfigForm-DVlhg3WV.js} +2 -2
- package/public/assets/{InitPassword-ZU9_-hDr.js → InitPassword-D7glTExX.js} +1 -1
- package/public/assets/InstanceDetail-CxSy2cpe.js +92 -0
- package/public/assets/{Login-BItXqYAJ.js → Login-Cfr5c2sv.js} +1 -1
- package/public/assets/NewInstance-BIYDmJis.js +1 -0
- package/public/assets/{ProviderRecommendations-DFYj7Fb6.js → ProviderRecommendations-BuRnvRcI.js} +1 -1
- package/public/assets/{Settings-Bttc6QmM.js → Settings-Cc-tYBil.js} +1 -1
- package/public/assets/{Setup-Bsxx1zgj.js → Setup-lGZEk5jq.js} +1 -1
- package/public/assets/{WeixinLoginPanel-DPZpAKgO.js → WeixinLoginPanel-CoGqzxeV.js} +2 -2
- package/public/assets/index-87IJXG-w.css +1 -0
- package/public/assets/index-BZc5zH7u.js +19 -0
- package/public/assets/{registry-5s2UB6is.js → registry-BWnkJgZ1.js} +2 -2
- package/public/assets/{usePolling-Do5Erqm_.js → usePolling-CwwT9KrC.js} +1 -1
- package/public/assets/{vendor-i18n-ucpM0OR0.js → vendor-i18n-y9V7Sfuu.js} +1 -1
- package/public/assets/{vendor-react-Bk1hRGiY.js → vendor-react-BWrEVJVb.js} +6 -6
- package/public/index.html +4 -4
- package/scripts/check-app-spec.mjs +18 -4
- package/scripts/check-new-file-tests.mjs +230 -0
- package/scripts/check-quarantine-expiry.mjs +105 -0
- package/scripts/perf/README.md +49 -0
- package/scripts/perf/auth.js +99 -0
- package/scripts/perf/config.js +63 -0
- package/scripts/perf/instances.js +143 -0
- package/scripts/perf/proxy.js +96 -0
- package/scripts/smoke/files-w1.sh +142 -0
- package/scripts/smoke-backend.mjs +122 -0
- package/scripts/smoke-post-publish.mjs +346 -0
- package/public/assets/Dashboard-rkWp-CXd.js +0 -1
- package/public/assets/InstanceDetail-CN0FH1aw.js +0 -92
- package/public/assets/NewInstance-BousE6kY.js +0 -1
- package/public/assets/index-8xZy1z5k.css +0 -1
- package/public/assets/index-Dw3HhUYE.js +0 -19
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Post-publish smoke test: install the published jishushell package from
|
|
4
|
+
* the npm registry into an isolated prefix, then verify it boots.
|
|
5
|
+
*
|
|
6
|
+
* Steps:
|
|
7
|
+
* 1. npm install -g jishushell@{version} --prefix <tempdir> --registry <url>
|
|
8
|
+
* 2. Verify `jishushell version` output matches the expected version
|
|
9
|
+
* 3. Spawn `jishushell serve --port 0 --host 127.0.0.1`
|
|
10
|
+
* 4. Poll /api/auth/status until HTTP 200
|
|
11
|
+
* 5. Clean up temp dirs and kill the server
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* node scripts/smoke-post-publish.mjs --version 0.4.30 [--registry http://...]
|
|
15
|
+
*
|
|
16
|
+
* Exit codes:
|
|
17
|
+
* 0 — smoke test passed
|
|
18
|
+
* 1 — smoke test failed
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { execFileSync, spawn } from "child_process";
|
|
22
|
+
import { mkdirSync, mkdtempSync, rmSync } from "fs";
|
|
23
|
+
import { tmpdir } from "os";
|
|
24
|
+
import { join } from "path";
|
|
25
|
+
import { setTimeout as delay } from "timers/promises";
|
|
26
|
+
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Constants
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
const DEFAULT_REGISTRY = "http://10.188.0.22:4873/";
|
|
32
|
+
const INSTALL_RETRY_ATTEMPTS = 3;
|
|
33
|
+
const INSTALL_RETRY_DELAY_MS = 2_000;
|
|
34
|
+
const STARTUP_TIMEOUT_MS = 20_000;
|
|
35
|
+
const HEALTH_POLL_INTERVAL_MS = 300;
|
|
36
|
+
const HEALTH_POLL_ATTEMPTS = 30;
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Argument parsing
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
function parseArgs() {
|
|
43
|
+
const args = process.argv.slice(2);
|
|
44
|
+
let version = "";
|
|
45
|
+
let registry = DEFAULT_REGISTRY;
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < args.length; i++) {
|
|
48
|
+
if (args[i] === "--version" && args[i + 1]) {
|
|
49
|
+
version = args[++i];
|
|
50
|
+
} else if (args[i] === "--registry" && args[i + 1]) {
|
|
51
|
+
registry = args[++i];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!version) {
|
|
56
|
+
console.error("[post-publish] ERROR: --version is required");
|
|
57
|
+
console.error("Usage: node scripts/smoke-post-publish.mjs --version 0.4.30 [--registry URL]");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { version, registry };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Version normalization
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
/** Strip leading 'v' for consistent comparison. */
|
|
69
|
+
function normalizeVersion(v) {
|
|
70
|
+
return v.trim().replace(/^v/, "");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Temp directory management
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
function createTempDirs() {
|
|
78
|
+
const base = mkdtempSync(join(tmpdir(), "jishushell-postpub-"));
|
|
79
|
+
const prefixDir = join(base, "npm-prefix");
|
|
80
|
+
const homeDir = join(base, "jishushell-home");
|
|
81
|
+
const cacheDir = join(base, "npm-cache");
|
|
82
|
+
const fakeHome = join(base, "fake-home");
|
|
83
|
+
|
|
84
|
+
for (const dir of [prefixDir, homeDir, cacheDir, fakeHome]) {
|
|
85
|
+
mkdirSync(dir, { recursive: true });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { base, prefixDir, homeDir, cacheDir, fakeHome };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// npm install with retry
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
async function npmInstallGlobal({ version, registry, prefixDir, cacheDir, fakeHome }) {
|
|
96
|
+
const pkg = `jishushell@${version}`;
|
|
97
|
+
const npmArgs = [
|
|
98
|
+
"install", "--global",
|
|
99
|
+
"--prefix", prefixDir,
|
|
100
|
+
"--registry", registry,
|
|
101
|
+
"--cache", cacheDir,
|
|
102
|
+
"--no-fund", "--no-audit",
|
|
103
|
+
pkg,
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
const env = {
|
|
107
|
+
...process.env,
|
|
108
|
+
HOME: fakeHome,
|
|
109
|
+
CI: "true",
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
for (let attempt = 1; attempt <= INSTALL_RETRY_ATTEMPTS; attempt++) {
|
|
113
|
+
try {
|
|
114
|
+
console.log(`[post-publish] npm install (attempt ${attempt}/${INSTALL_RETRY_ATTEMPTS}): ${pkg}`);
|
|
115
|
+
execFileSync("npm", npmArgs, {
|
|
116
|
+
encoding: "utf-8",
|
|
117
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
118
|
+
timeout: 120_000,
|
|
119
|
+
env,
|
|
120
|
+
});
|
|
121
|
+
console.log(`[post-publish] Install succeeded`);
|
|
122
|
+
return;
|
|
123
|
+
} catch (err) {
|
|
124
|
+
const stderr = err.stderr?.toString() || err.message;
|
|
125
|
+
console.error(`[post-publish] Install attempt ${attempt} failed: ${stderr.slice(0, 500)}`);
|
|
126
|
+
if (attempt < INSTALL_RETRY_ATTEMPTS) {
|
|
127
|
+
await delay(INSTALL_RETRY_DELAY_MS);
|
|
128
|
+
} else {
|
|
129
|
+
throw new Error(`npm install failed after ${INSTALL_RETRY_ATTEMPTS} attempts`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
// Version verification
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
function verifyVersion({ binPath, expectedVersion, fakeHome }) {
|
|
140
|
+
console.log(`[post-publish] Verifying version: ${binPath} version`);
|
|
141
|
+
|
|
142
|
+
const output = execFileSync("node", [binPath, "version"], {
|
|
143
|
+
encoding: "utf-8",
|
|
144
|
+
timeout: 10_000,
|
|
145
|
+
env: {
|
|
146
|
+
...process.env,
|
|
147
|
+
HOME: fakeHome,
|
|
148
|
+
NODE_ENV: "test",
|
|
149
|
+
npm_package_version: "",
|
|
150
|
+
},
|
|
151
|
+
}).trim();
|
|
152
|
+
|
|
153
|
+
const actual = normalizeVersion(output.split("\n").filter(Boolean).pop() || "");
|
|
154
|
+
const expected = normalizeVersion(expectedVersion);
|
|
155
|
+
|
|
156
|
+
if (actual !== expected) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Version mismatch: expected '${expected}', got '${actual}' (raw output: '${output}')`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
console.log(`[post-publish] Version OK: ${output}`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Server boot + health check
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
|
|
169
|
+
async function verifyServerBoots({ binPath, homeDir, fakeHome }) {
|
|
170
|
+
console.log(`[post-publish] Starting server: ${binPath} serve --port 0 --host 127.0.0.1`);
|
|
171
|
+
|
|
172
|
+
let serverProcess;
|
|
173
|
+
try {
|
|
174
|
+
serverProcess = spawn("node", [binPath, "serve", "--port", "0", "--host", "127.0.0.1"], {
|
|
175
|
+
env: {
|
|
176
|
+
...process.env,
|
|
177
|
+
HOME: fakeHome,
|
|
178
|
+
JISHUSHELL_HOME: homeDir,
|
|
179
|
+
JISHUSHELL_JWT_SECRET: "ci-smoke-test-jwt-secret-that-is-at-least-32-chars",
|
|
180
|
+
NODE_ENV: "test",
|
|
181
|
+
npm_package_version: "",
|
|
182
|
+
},
|
|
183
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
184
|
+
});
|
|
185
|
+
} catch (err) {
|
|
186
|
+
console.error(`[post-publish] Failed to spawn server process: ${err.message}`);
|
|
187
|
+
throw err;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
serverProcessRef = serverProcess;
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
// Discover the assigned port from stdout/stderr
|
|
194
|
+
const port = await new Promise((resolve, reject) => {
|
|
195
|
+
const timer = setTimeout(
|
|
196
|
+
() => reject(new Error("Server did not start within timeout")),
|
|
197
|
+
STARTUP_TIMEOUT_MS,
|
|
198
|
+
);
|
|
199
|
+
let output = "";
|
|
200
|
+
|
|
201
|
+
const onData = (chunk) => {
|
|
202
|
+
output += chunk.toString();
|
|
203
|
+
const match = output.match(/listening at http:\/\/127\.0\.0\.1:(\d+)/);
|
|
204
|
+
if (match) {
|
|
205
|
+
clearTimeout(timer);
|
|
206
|
+
resolve(parseInt(match[1], 10));
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
serverProcess.stdout.on("data", onData);
|
|
211
|
+
serverProcess.stderr.on("data", onData);
|
|
212
|
+
serverProcess.on("exit", (code) => {
|
|
213
|
+
clearTimeout(timer);
|
|
214
|
+
reject(
|
|
215
|
+
new Error(
|
|
216
|
+
`Server exited with code ${code} before becoming ready.\nOutput:\n${output}`,
|
|
217
|
+
),
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
console.log(`[post-publish] Server listening on port ${port}`);
|
|
223
|
+
|
|
224
|
+
// Poll /api/auth/status
|
|
225
|
+
let lastStatus = 0;
|
|
226
|
+
for (let i = 0; i < HEALTH_POLL_ATTEMPTS; i++) {
|
|
227
|
+
try {
|
|
228
|
+
const resp = await fetch(`http://127.0.0.1:${port}/api/auth/status`, {
|
|
229
|
+
signal: AbortSignal.timeout(2000),
|
|
230
|
+
});
|
|
231
|
+
lastStatus = resp.status;
|
|
232
|
+
if (resp.ok) {
|
|
233
|
+
console.log(`[post-publish] PASSED: /api/auth/status returned ${resp.status}`);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
} catch {
|
|
237
|
+
// Server may not be fully ready yet
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (serverProcess.exitCode !== null) {
|
|
241
|
+
throw new Error(
|
|
242
|
+
`Server exited unexpectedly with code ${serverProcess.exitCode}`,
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
await delay(HEALTH_POLL_INTERVAL_MS);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
throw new Error(
|
|
250
|
+
`/api/auth/status returned ${lastStatus} after ${HEALTH_POLL_ATTEMPTS} attempts`,
|
|
251
|
+
);
|
|
252
|
+
} finally {
|
|
253
|
+
// Always kill the server process
|
|
254
|
+
if (!serverProcess.killed && serverProcess.exitCode === null) {
|
|
255
|
+
serverProcess.kill("SIGTERM");
|
|
256
|
+
await delay(500);
|
|
257
|
+
if (serverProcess.exitCode === null) {
|
|
258
|
+
try {
|
|
259
|
+
serverProcess.kill("SIGKILL");
|
|
260
|
+
} catch {
|
|
261
|
+
/* already dead */
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
// Process-level cleanup (CI cancel / timeout sends SIGTERM)
|
|
270
|
+
// ---------------------------------------------------------------------------
|
|
271
|
+
|
|
272
|
+
let serverProcessRef = null;
|
|
273
|
+
let tempBaseDir = null;
|
|
274
|
+
|
|
275
|
+
function emergencyCleanup(exitCode) {
|
|
276
|
+
if (serverProcessRef && !serverProcessRef.killed) {
|
|
277
|
+
try { serverProcessRef.kill("SIGKILL"); } catch { /* already dead */ }
|
|
278
|
+
}
|
|
279
|
+
if (tempBaseDir) {
|
|
280
|
+
try { rmSync(tempBaseDir, { recursive: true, force: true }); } catch { /* noop */ }
|
|
281
|
+
}
|
|
282
|
+
process.exit(exitCode);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
process.on("SIGINT", () => emergencyCleanup(1));
|
|
286
|
+
process.on("SIGTERM", () => emergencyCleanup(1));
|
|
287
|
+
process.on("unhandledRejection", (err) => {
|
|
288
|
+
console.error("[post-publish] unhandled rejection:", err);
|
|
289
|
+
emergencyCleanup(1);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
// Main
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
|
|
296
|
+
async function main() {
|
|
297
|
+
const { version, registry } = parseArgs();
|
|
298
|
+
const dirs = createTempDirs();
|
|
299
|
+
tempBaseDir = dirs.base;
|
|
300
|
+
|
|
301
|
+
const binPath = join(dirs.prefixDir, "bin", "jishushell");
|
|
302
|
+
|
|
303
|
+
console.log(`[post-publish] ─────────────────────────────────────────`);
|
|
304
|
+
console.log(`[post-publish] Version: ${version}`);
|
|
305
|
+
console.log(`[post-publish] Registry: ${registry}`);
|
|
306
|
+
console.log(`[post-publish] Prefix: ${dirs.prefixDir}`);
|
|
307
|
+
console.log(`[post-publish] Home: ${dirs.homeDir}`);
|
|
308
|
+
console.log(`[post-publish] ─────────────────────────────────────────`);
|
|
309
|
+
|
|
310
|
+
try {
|
|
311
|
+
await npmInstallGlobal({
|
|
312
|
+
version,
|
|
313
|
+
registry,
|
|
314
|
+
prefixDir: dirs.prefixDir,
|
|
315
|
+
cacheDir: dirs.cacheDir,
|
|
316
|
+
fakeHome: dirs.fakeHome,
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
verifyVersion({
|
|
320
|
+
binPath,
|
|
321
|
+
expectedVersion: version,
|
|
322
|
+
fakeHome: dirs.fakeHome,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
await verifyServerBoots({
|
|
326
|
+
binPath,
|
|
327
|
+
homeDir: dirs.homeDir,
|
|
328
|
+
fakeHome: dirs.fakeHome,
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
console.log(`[post-publish] ✅ Post-publish smoke test PASSED`);
|
|
332
|
+
} finally {
|
|
333
|
+
// Clean up all temp directories
|
|
334
|
+
try {
|
|
335
|
+
rmSync(dirs.base, { recursive: true, force: true });
|
|
336
|
+
console.log(`[post-publish] Cleaned up temp dirs`);
|
|
337
|
+
} catch {
|
|
338
|
+
console.warn(`[post-publish] Warning: failed to clean up ${dirs.base}`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
main().catch((err) => {
|
|
344
|
+
console.error(`[post-publish] ❌ FAILED: ${err.message}`);
|
|
345
|
+
process.exit(1);
|
|
346
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{k as B,j as e,L as K,l as $,m as A,n as L,o as I,q as T,t as E,v as M,w as R,x as U}from"./index-Dw3HhUYE.js";import{r as u,u as D}from"./vendor-react-Bk1hRGiY.js";import{u as P}from"./usePolling-Do5Erqm_.js";import{u as _}from"./vendor-i18n-ucpM0OR0.js";function G(t){if(!t)return"-";const l=Math.floor(t/86400),o=Math.floor(t%86400/3600),r=Math.floor(t%3600/60);return l>0?`${l}d ${o}h`:o>0?`${o}h ${r}m`:`${r}m`}function q({status:t}){const{t:l}=_(),r={running:{cls:"bg-emerald-500/10 text-emerald-400 border border-emerald-500/20",labelKey:"status.running"},pending:{cls:"bg-amber-500/10 text-amber-400 border border-amber-500/20",labelKey:"status.starting"},failed:{cls:"bg-red-500/10 text-red-400 border border-red-500/20",labelKey:"status.failed"},dead:{cls:"bg-red-500/10 text-red-400 border border-red-500/20",labelKey:"status.crashed"}}[t]||{cls:"bg-[var(--card)] text-muted border border-[var(--border)]",labelKey:"status.stopped"};return e.jsx("span",{className:`inline-flex items-center text-xs px-2 py-0.5 rounded-full font-medium ${r.cls}`,children:l(r.labelKey)})}const O=[{key:"localInference",labelKey:"capability.localInference",cls:"bg-emerald-500/10 text-emerald-400 border-emerald-500/20"},{key:"search",labelKey:"capability.search",cls:"bg-sky-500/10 text-sky-400 border-sky-500/20"},{key:"browser",labelKey:"capability.browser",cls:"bg-violet-500/10 text-violet-400 border-violet-500/20"},{key:"aiWebUi",labelKey:"capability.aiWebUi",cls:"bg-cyan-500/10 text-cyan-400 border-cyan-500/20"},{key:"webUi",labelKey:"capability.webUi",cls:"bg-slate-500/10 text-muted border-[var(--border)]"}];function V(t){const l=new Set((Array.isArray(t==null?void 0:t.provides)?t.provides:[]).map(a=>String((a==null?void 0:a.capability)??"").toLowerCase()).filter(Boolean));if(l.has("llm-agent"))return[];const o=a=>{for(const m of l)if(a(m))return!0;return!1},r=new Set;return o(a=>a==="llm-ollama"||a==="ollama-api")&&r.add("localInference"),o(a=>a==="search"||a.startsWith("search-"))&&r.add("search"),o(a=>a==="browser"||a.startsWith("browser-")||a.startsWith("web-browserless")||a.startsWith("playwright"))&&r.add("browser"),o(a=>a.includes("openwebui"))&&r.add("aiWebUi"),!r.size&&o(a=>a.startsWith("web-")||a.endsWith("-web")||a.endsWith("-dashboard"))&&r.add("webUi"),O.filter(a=>r.has(a.key))}function Q(){const{t}=_(["dashboard","common"]),[l,o]=u.useState([]),[r,a]=u.useState(null),[m,v]=u.useState(""),[j,w]=u.useState(""),[g,N]=u.useState(!1),y=D(),{showToast:b}=B(),h=()=>{I().then(s=>{o(s),w("")}).catch(s=>w(s.message||t("common:error.loadFailed"))),T().then(a).catch(()=>{})};P(h,1e4);const F=async()=>{if(window.confirm(t("engine.restartConfirm"))){N(!0);try{await E(),b(t("engine.restarted"),"success"),setTimeout(h,2e3)}catch(s){b(s.message||t("engine.restartFailed"),"error")}finally{N(!1)}}},f=async(s,n,x)=>{s.stopPropagation(),v(`${x}-${n}`);try{let i=null;n==="start"&&(i=await M(x)),n==="stop"&&(i=await R(x)),n==="restart"&&(i=await U(x)),b(t(`common:action.${n}Done`),"success");const d=i==null?void 0:i.port_allocation;d&&typeof d.from=="number"&&typeof d.to=="number"&&d.from!==d.to&&b(t("common:toast.portReallocated",{defaultValue:"端口 {{from}} 被占用,已自动切换到 {{to}}",from:d.from,to:d.to}),"info"),setTimeout(h,1e3)}catch(i){b(i.message||t("common:error.operationFailed"),"error")}finally{v("")}},S=l.filter(s=>{var n;return((n=s.service)==null?void 0:n.status)==="running"}).length,p=!!r&&r.disk.percent>90,W=r?[{label:t("stats.runningInstances"),value:`${S} / ${l.length}`,sub:r.nomad_running?t("stats.engineRunning"):t("stats.engineStopped"),subColor:r.nomad_running?"text-emerald-400":"text-red-400",icon:e.jsxs("svg",{className:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,children:[e.jsx("rect",{x:"2",y:"3",width:"20",height:"14",rx:"2"}),e.jsx("line",{x1:"8",y1:"21",x2:"16",y2:"21"}),e.jsx("line",{x1:"12",y1:"17",x2:"12",y2:"21"})]}),iconColor:"text-[#0066FF]",glowColor:"rgba(0,102,255,0.12)",accent:"border-l-2 border-l-[#0066FF]"},{label:t("stats.cpu"),value:`${r.cpu_percent}%`,sub:r.temperature?`${r.temperature}°C`:null,icon:e.jsxs("svg",{className:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,children:[e.jsx("rect",{x:"4",y:"4",width:"16",height:"16",rx:"2"}),e.jsx("rect",{x:"9",y:"9",width:"6",height:"6"}),e.jsx("line",{x1:"9",y1:"2",x2:"9",y2:"4"}),e.jsx("line",{x1:"15",y1:"2",x2:"15",y2:"4"}),e.jsx("line",{x1:"9",y1:"20",x2:"9",y2:"22"}),e.jsx("line",{x1:"15",y1:"20",x2:"15",y2:"22"}),e.jsx("line",{x1:"20",y1:"9",x2:"22",y2:"9"}),e.jsx("line",{x1:"20",y1:"15",x2:"22",y2:"15"}),e.jsx("line",{x1:"2",y1:"9",x2:"4",y2:"9"}),e.jsx("line",{x1:"2",y1:"15",x2:"4",y2:"15"})]}),iconColor:"text-[#0066FF]",glowColor:"rgba(0,102,255,0.12)",accent:"border-l-2 border-l-[#0066FF]",warn:r.cpu_percent>90},{label:t("stats.memory"),value:`${r.memory.percent}%`,sub:`${r.memory.used_mb}MB / ${r.memory.total_mb}MB`,icon:e.jsx("svg",{className:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,children:e.jsx("path",{d:"M6 19v-8m4 8v-4m4 4v-6m4 6v-2"})}),iconColor:"text-[#00D4AA]",glowColor:"rgba(0,212,170,0.12)",accent:"border-l-2 border-l-[#00D4AA]"},{label:t("stats.disk"),value:`${r.disk.percent}%`,sub:`${r.disk.used_gb}GB / ${r.disk.total_gb}GB`,icon:e.jsxs("svg",{className:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,children:[e.jsx("ellipse",{cx:"12",cy:"5",rx:"9",ry:"3"}),e.jsx("path",{d:"M3 5v14a9 3 0 0018 0V5"}),e.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"22"})]}),iconColor:p?"text-red-400":"text-[#0066FF]",glowColor:p?"rgba(239,68,68,0.12)":"rgba(0,102,255,0.12)",accent:p?"border-l-2 border-l-red-400":"border-l-2 border-l-[#0066FF]",warn:p}]:[];return e.jsxs("div",{className:"p-4 max-w-5xl mx-auto",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-base font-semibold text-foreground",children:t("title")}),e.jsx("p",{className:"text-xs text-muted mt-0.5",children:t("subtitle")})]}),e.jsx(K,{})]}),r&&e.jsx("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-3 mb-4",children:W.map(s=>e.jsxs("div",{className:`bg-[var(--card)] border border-[var(--border)] rounded-lg p-3 relative overflow-hidden hover:border-[var(--border-hover)] hover:bg-[var(--card-hover)] transition-all duration-200 ${s.accent}`,children:[e.jsx("div",{className:"absolute top-0 right-0 w-16 h-16 rounded-full opacity-60 pointer-events-none",style:{background:`radial-gradient(circle, ${s.glowColor} 0%, transparent 70%)`}}),e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsx("span",{className:"text-[11px] text-muted",children:s.label}),e.jsx("span",{className:`${s.iconColor} opacity-80`,children:s.icon})]}),e.jsx("div",{className:`text-lg font-semibold ${s.warn?"text-red-400":"text-foreground"}`,children:s.value}),s.sub&&e.jsx("div",{className:`text-[11px] mt-0.5 truncate ${s.subColor??"text-muted"}`,children:s.sub})]},s.label))}),e.jsxs("div",{className:"bg-[var(--card)] border border-[var(--border)] rounded-xl overflow-hidden",children:[e.jsxs("div",{className:"px-4 py-2.5 border-b border-[var(--border)] flex items-center justify-between",children:[e.jsx("h2",{className:"text-sm font-medium text-foreground",children:t("instances.title")}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:()=>y("/instances/new"),className:"bg-[#0066FF] text-white px-3 py-1.5 rounded-md text-xs font-medium hover:bg-[#0066FF]/90 transition-all duration-200 shadow-[0_0_12px_rgba(0,102,255,0.3)]",children:t("instances.new")}),e.jsx("button",{onClick:()=>y("/instances/new?import=true"),className:"px-3 py-1.5 rounded-md text-xs font-medium text-muted border border-[var(--border)] bg-[var(--card)] hover:bg-[var(--card-hover)] hover:text-foreground transition-all duration-200",children:t("instances.import")}),e.jsxs("button",{onClick:F,disabled:g,title:t("instances.restartEngineTitle"),className:"flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium text-red-400 border border-red-500/20 bg-red-500/5 hover:bg-red-500/15 disabled:opacity-40 disabled:cursor-not-allowed transition-all duration-200",children:[e.jsx($,{className:`w-3 h-3 ${g?"animate-spin":""}`}),t(g?"instances.restarting":"instances.restartEngine")]})]})]}),j?e.jsxs("div",{className:"text-center py-12 px-4",children:[e.jsx("p",{className:"text-sm text-red-400 mb-2",children:t("instances.loadError",{error:j})}),e.jsx("button",{onClick:h,className:"text-xs text-muted hover:text-foreground underline",children:t("common:action.retry")})]}):l.length===0?e.jsxs("div",{className:"text-center py-12 px-4",children:[e.jsx("div",{className:"text-muted opacity-40 mb-3",children:e.jsxs("svg",{className:"w-8 h-8 mx-auto",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1,strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("rect",{x:"2",y:"3",width:"20",height:"14",rx:"2"}),e.jsx("line",{x1:"8",y1:"21",x2:"16",y2:"21"}),e.jsx("line",{x1:"12",y1:"17",x2:"12",y2:"21"})]})}),e.jsx("p",{className:"text-sm text-muted mb-1",children:t("instances.empty")}),e.jsx("p",{className:"text-xs text-muted opacity-60",children:t("instances.emptyHint")})]}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-xs text-muted border-b border-[var(--border)]",children:[e.jsx("th",{className:"text-left font-medium px-4 py-2",children:t("table.name")}),e.jsx("th",{className:"text-left font-medium px-4 py-2",children:t("table.status")}),e.jsx("th",{className:"text-left font-medium px-4 py-2 hidden sm:table-cell",children:t("table.uptime")}),e.jsx("th",{className:"text-left font-medium px-4 py-2 hidden md:table-cell",children:t("table.memory")}),e.jsx("th",{className:"text-left font-medium px-4 py-2 hidden lg:table-cell",children:t("table.localCapability")}),e.jsx("th",{className:"text-right font-medium px-4 py-2",children:t("table.actions")})]})}),e.jsx("tbody",{className:"divide-y divide-[var(--border)]",children:l.map(s=>{var d,k,C;const n=((d=s.service)==null?void 0:d.status)||"stopped",x=n==="running",i=V(s);return e.jsxs("tr",{className:"hover:bg-[var(--card-hover)] cursor-pointer transition-colors duration-150",onClick:()=>y(`/instances/${s.id}`),children:[e.jsxs("td",{className:"px-4 py-2.5",children:[e.jsx("div",{className:"font-medium text-foreground",children:s.name}),e.jsx("div",{className:"text-xs text-muted font-mono",children:s.id})]}),e.jsx("td",{className:"px-4 py-2.5",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(q,{status:n}),((k=s.auto_backup)==null?void 0:k.enabled)&&e.jsx("span",{className:`text-xs leading-none ${s.auto_backup.last_backup_ok===!1?"text-red-400":"text-green-400"}`,title:s.auto_backup.last_backup_ok===!1?"Backup failed":"Backup OK",children:s.auto_backup.last_backup_ok===!1?"⚠":"●"})]})}),e.jsx("td",{className:"px-4 py-2.5 text-muted hidden sm:table-cell font-mono text-xs",children:x?G(s.service.uptime):"-"}),e.jsx("td",{className:"px-4 py-2.5 text-muted hidden md:table-cell font-mono text-xs",children:(C=s.service)!=null&&C.memory_mb?`${s.service.memory_mb} MB`:"-"}),e.jsx("td",{className:"px-4 py-2.5 hidden lg:table-cell",children:i.length?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:i.map(c=>e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-medium ${c.cls}`,children:t(c.labelKey)},c.key))}):e.jsx("span",{className:"text-muted text-xs",children:"-"})}),e.jsx("td",{className:"px-4 py-2.5 text-right",children:e.jsx("div",{className:"inline-flex items-center gap-1",children:x||n==="pending"?e.jsxs(e.Fragment,{children:[e.jsx("button",{title:t("common:action.restart"),onClick:c=>f(c,"restart",s.id),disabled:!!m,className:"p-1.5 rounded-md text-muted hover:text-foreground hover:bg-[var(--card-hover)] disabled:opacity-30 transition-colors duration-150",children:e.jsx($,{className:"w-3.5 h-3.5"})}),e.jsx("button",{title:t("common:action.stop"),onClick:c=>f(c,"stop",s.id),disabled:!!m,className:"p-1.5 rounded-md text-muted hover:text-red-400 hover:bg-red-500/10 disabled:opacity-30 transition-colors duration-150",children:e.jsx(A,{className:"w-3.5 h-3.5"})})]}):e.jsx("button",{title:t("common:action.start"),onClick:c=>f(c,"start",s.id),disabled:!!m,className:"p-1.5 rounded-md text-muted hover:text-emerald-400 hover:bg-emerald-500/10 disabled:opacity-30 transition-colors duration-150",children:e.jsx(L,{className:"w-3.5 h-3.5"})})})})]},s.id)})})]})]})]})}export{Q as default};
|