@kw-yeh/vibeflow 4.11.17 → 4.11.18
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/vibeflow.mjs +184 -48
- package/dist/web/404/index.html +1 -1
- package/dist/web/404.html +1 -1
- package/dist/web/_next/static/chunks/pages/{_app-83dfa6752c321c56.js → _app-2571a2564f593899.js} +1 -1
- package/dist/web/_next/static/chunks/pages/{home-61c688b1d20e56ff.js → home-5e349dff04afe2eb.js} +7 -7
- package/dist/web/_next/static/{xoex8UtSV4DX9eSoX3lTZ → wiyRNf4HeW4AW-LhhYSsf}/_buildManifest.js +1 -1
- package/dist/web/home/index.html +1 -1
- package/package.json +1 -1
- /package/dist/web/_next/static/{xoex8UtSV4DX9eSoX3lTZ → wiyRNf4HeW4AW-LhhYSsf}/_ssgManifest.js +0 -0
package/dist/vibeflow.mjs
CHANGED
|
@@ -1090,9 +1090,9 @@ var init_progress = __esm({
|
|
|
1090
1090
|
|
|
1091
1091
|
// packages/tui/src/task-form.ts
|
|
1092
1092
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
1093
|
-
import
|
|
1093
|
+
import fs25 from "fs";
|
|
1094
1094
|
import os8 from "os";
|
|
1095
|
-
import
|
|
1095
|
+
import path29 from "path";
|
|
1096
1096
|
import React, { useEffect, useRef, useState } from "react";
|
|
1097
1097
|
import { Box, Text, render as render2, useApp, useInput } from "ink";
|
|
1098
1098
|
function newFormState(defaultAutoMode, agents) {
|
|
@@ -1218,17 +1218,17 @@ function editorCommand(env, platform) {
|
|
|
1218
1218
|
return env.VISUAL?.trim() || env.EDITOR?.trim() || (platform === "win32" ? "notepad" : "vi");
|
|
1219
1219
|
}
|
|
1220
1220
|
function editInEditor(text) {
|
|
1221
|
-
const dir =
|
|
1222
|
-
const file =
|
|
1221
|
+
const dir = fs25.mkdtempSync(path29.join(os8.tmpdir(), "vibeflow-"));
|
|
1222
|
+
const file = path29.join(dir, "description.md");
|
|
1223
1223
|
try {
|
|
1224
|
-
|
|
1224
|
+
fs25.writeFileSync(file, text);
|
|
1225
1225
|
const cmd = editorCommand(process.env, process.platform);
|
|
1226
1226
|
const r = spawnSync2(`${cmd} "${file}"`, { stdio: "inherit", shell: true });
|
|
1227
1227
|
if (r.error) return { error: `\u7121\u6CD5\u555F\u52D5\u7DE8\u8F2F\u5668\uFF08${cmd}\uFF09\uFF1A${r.error.message}` };
|
|
1228
1228
|
if (r.status !== 0) return { error: `\u7DE8\u8F2F\u5668\uFF08${cmd}\uFF09\u7D50\u675F\u78BC ${r.status}\uFF0C\u63CF\u8FF0\u672A\u8B8A\u66F4` };
|
|
1229
|
-
return { text:
|
|
1229
|
+
return { text: fs25.readFileSync(file, "utf8").replace(/\r?\n$/, "") };
|
|
1230
1230
|
} finally {
|
|
1231
|
-
|
|
1231
|
+
fs25.rmSync(dir, { recursive: true, force: true });
|
|
1232
1232
|
}
|
|
1233
1233
|
}
|
|
1234
1234
|
function cycle(list, current, step) {
|
|
@@ -1299,10 +1299,10 @@ function FormView({ api, ctx, initial, initialFocus, initialMessage, pristine, o
|
|
|
1299
1299
|
if (editing === "title") setS((prev) => ({ ...prev, title: draft }));
|
|
1300
1300
|
else if (editing === "branch") setS((prev) => ({ ...prev, branch: value2 }));
|
|
1301
1301
|
else if (editing === "project") {
|
|
1302
|
-
if (value2) setProject(
|
|
1302
|
+
if (value2) setProject(path29.resolve(value2.replace(/^~(?=$|\/)/, os8.homedir())));
|
|
1303
1303
|
} else if (editing === "attachments" && value2) {
|
|
1304
|
-
const file =
|
|
1305
|
-
if (!
|
|
1304
|
+
const file = path29.resolve(value2.replace(/^~(?=$|\/)/, os8.homedir()));
|
|
1305
|
+
if (!fs25.existsSync(file) || !fs25.statSync(file).isFile()) {
|
|
1306
1306
|
setMessage(`\u627E\u4E0D\u5230\u6A94\u6848\uFF1A${file}`);
|
|
1307
1307
|
return;
|
|
1308
1308
|
}
|
|
@@ -1385,7 +1385,7 @@ function FormView({ api, ctx, initial, initialFocus, initialMessage, pristine, o
|
|
|
1385
1385
|
case "branch":
|
|
1386
1386
|
return s.branch || "\uFF08\u7559\u7A7A\u5247\u81EA\u52D5\u547D\u540D\uFF0C\u4F8B\u5982 feature/login-fix\uFF09";
|
|
1387
1387
|
case "attachments":
|
|
1388
|
-
return s.attachments.length ? s.attachments.map((a) =>
|
|
1388
|
+
return s.attachments.length ? s.attachments.map((a) => path29.basename(a)).join("\u3001") : "\uFF08Enter \u8F38\u5165\u6A94\u6848\u8DEF\u5F91\u52A0\u5165\uFF09";
|
|
1389
1389
|
case "description": {
|
|
1390
1390
|
if (!s.description) return "\uFF08Enter \u7528\u7DE8\u8F2F\u5668\u64B0\u5BEB\uFF09";
|
|
1391
1391
|
const lines = s.description.split("\n");
|
|
@@ -1420,7 +1420,7 @@ function FormView({ api, ctx, initial, initialFocus, initialMessage, pristine, o
|
|
|
1420
1420
|
if (info && !info.isRepo) return "\u9019\u500B\u8CC7\u6599\u593E\u4E0D\u662F Git repository\u3002\u8ACB\u6539\u9078\u4E00\u500B Git \u5C08\u6848\uFF0C\u6216\u5728\u4E0B\u65B9\u521D\u59CB\u5316\u3002";
|
|
1421
1421
|
if (s.mode === "edit" && projectChanged(s)) return "\u5206\u652F\u6703\u5728\u65B0\u5C08\u6848\u3001\u5361\u7247\u958B\u59CB\u57F7\u884C\u6642\u624D\u5EFA\u7ACB\u3002";
|
|
1422
1422
|
if (info?.isRepo && !info.hasRemote) return `\u6B64 repository \u6C92\u6709 remote\uFF0C\u5C07\u4EE5\u76EE\u524D\u5206\u652F (${info.currentBranch ?? "HEAD"}) \u70BA\u57FA\u6E96\u5EFA\u7ACB\u672C\u5730 worktree\u3002`;
|
|
1423
|
-
if (info?.isRepo && s.projectPath) return `worktree \u6703\u5EFA\u5728 ${ctx.workstationPath || "~/Desktop"}/${
|
|
1423
|
+
if (info?.isRepo && s.projectPath) return `worktree \u6703\u5EFA\u5728 ${ctx.workstationPath || "~/Desktop"}/${path29.basename(s.projectPath)}`;
|
|
1424
1424
|
}
|
|
1425
1425
|
if (field === "branch") {
|
|
1426
1426
|
const when = info?.hasRemote ? "\u958B\u59CB\u57F7\u884C\u6642\u6703\u5EFA\u7ACB\u540C\u540D\u5206\u652F\u4E26\u63A8\u5230 origin\uFF1B\u82E5 remote \u5DF2\u6709\u9019\u500B\u5206\u652F\uFF0C\u5247\u76F4\u63A5\u53D6\u56DE\u4E26\u63A5\u7E8C\u4E0A\u9762\u7684\u5DE5\u4F5C\u3002" : "\u958B\u59CB\u57F7\u884C\u6642\u6703\u5EFA\u7ACB\u540C\u540D\u5206\u652F\u3002";
|
|
@@ -1549,7 +1549,7 @@ __export(src_exports, {
|
|
|
1549
1549
|
showDiff: () => showDiff
|
|
1550
1550
|
});
|
|
1551
1551
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
1552
|
-
import
|
|
1552
|
+
import path30 from "path";
|
|
1553
1553
|
import React2, { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1554
1554
|
import { Box as Box2, Text as Text2, render as render3, useApp as useApp2, useInput as useInput2, useStdout } from "ink";
|
|
1555
1555
|
function findDetachKey(text) {
|
|
@@ -1845,7 +1845,7 @@ function showDiff(task) {
|
|
|
1845
1845
|
});
|
|
1846
1846
|
}
|
|
1847
1847
|
function tmuxAttach(opts, sessionName) {
|
|
1848
|
-
const conf =
|
|
1848
|
+
const conf = path30.join(opts.userDataDir, "tmux.conf");
|
|
1849
1849
|
const inOurServer = (process.env.TMUX ?? "").split(",")[0].endsWith(`/${TMUX_SOCKET}`);
|
|
1850
1850
|
const args = inOurServer ? ["-L", TMUX_SOCKET, "-f", conf, "switch-client", "-t", `=${sessionName}`] : ["-L", TMUX_SOCKET, "-f", conf, "attach-session", "-t", `=${sessionName}`];
|
|
1851
1851
|
spawnSync3("tmux", args, { stdio: "inherit", env: { ...process.env, TMUX: inOurServer ? process.env.TMUX : "" } });
|
|
@@ -1976,10 +1976,11 @@ var init_src = __esm({
|
|
|
1976
1976
|
});
|
|
1977
1977
|
|
|
1978
1978
|
// packages/cli/src/main.ts
|
|
1979
|
-
import
|
|
1980
|
-
import
|
|
1979
|
+
import fs26 from "fs";
|
|
1980
|
+
import path31 from "path";
|
|
1981
1981
|
import { fileURLToPath } from "url";
|
|
1982
1982
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
1983
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
1983
1984
|
|
|
1984
1985
|
// packages/core/src/lock.ts
|
|
1985
1986
|
import fs from "fs";
|
|
@@ -4693,8 +4694,8 @@ async function taskCommand(argv) {
|
|
|
4693
4694
|
}
|
|
4694
4695
|
|
|
4695
4696
|
// packages/cli/src/host.ts
|
|
4696
|
-
import
|
|
4697
|
-
import
|
|
4697
|
+
import fs23 from "fs";
|
|
4698
|
+
import path27 from "path";
|
|
4698
4699
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
4699
4700
|
|
|
4700
4701
|
// packages/core/src/events.ts
|
|
@@ -7917,7 +7918,7 @@ function runUpdate(options) {
|
|
|
7917
7918
|
error(`\u66F4\u65B0\u5931\u6557\uFF1A${result.error?.message ?? `npm \u7D50\u675F\u78BC ${result.status ?? "unknown"}`}`);
|
|
7918
7919
|
return result.status && result.status > 0 ? result.status : 1;
|
|
7919
7920
|
}
|
|
7920
|
-
log("\u66F4\u65B0\u5B8C\u6210\u3002\
|
|
7921
|
+
log("\u66F4\u65B0\u5B8C\u6210\u3002\u57F7\u884C\u4E2D\u7684 Web UI host \u6703\u5728\u6578\u79D2\u5167\u81EA\u52D5\u91CD\u65B0\u555F\u52D5\u6210\u65B0\u7248\u672C\uFF1BTUI host \u6216\u6709\u57F7\u884C\u4E2D session \u7684 pty host \u8ACB\u81EA\u884C\u91CD\u65B0\u555F\u52D5\u3002");
|
|
7921
7922
|
return 0;
|
|
7922
7923
|
}
|
|
7923
7924
|
|
|
@@ -7971,6 +7972,17 @@ function createUpdateMonitor(options) {
|
|
|
7971
7972
|
}
|
|
7972
7973
|
return next ? { status: "available", ...next } : { status: "current", currentVersion: options.currentVersion };
|
|
7973
7974
|
},
|
|
7975
|
+
/** A newer version is on disk but the host must be restarted by hand to run it. */
|
|
7976
|
+
markInstalled(version, reason) {
|
|
7977
|
+
if (stopped || available?.installedVersion === version && available.restartBlocked === reason) return;
|
|
7978
|
+
available = {
|
|
7979
|
+
currentVersion: options.currentVersion,
|
|
7980
|
+
latestVersion: available && isNewerVersion(available.latestVersion, version) ? available.latestVersion : version,
|
|
7981
|
+
installedVersion: version,
|
|
7982
|
+
restartBlocked: reason
|
|
7983
|
+
};
|
|
7984
|
+
options.onChange(available);
|
|
7985
|
+
},
|
|
7974
7986
|
stop() {
|
|
7975
7987
|
stopped = true;
|
|
7976
7988
|
}
|
|
@@ -8037,6 +8049,70 @@ async function openUpdateTerminal(platform = process.platform, run3 = launch) {
|
|
|
8037
8049
|
throw new Error("\u627E\u4E0D\u5230\u53EF\u7528\u7684\u7D42\u7AEF\u6A5F\uFF0C\u8ACB\u624B\u52D5\u57F7\u884C\u66F4\u65B0\u6307\u4EE4\u3002");
|
|
8038
8050
|
}
|
|
8039
8051
|
|
|
8052
|
+
// packages/cli/src/self-update.ts
|
|
8053
|
+
import fs22 from "node:fs";
|
|
8054
|
+
import path26 from "node:path";
|
|
8055
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
8056
|
+
import { promisify as promisify7 } from "node:util";
|
|
8057
|
+
var execFileAsync2 = promisify7(execFile10);
|
|
8058
|
+
var INSTALL_POLL_INTERVAL_MS = 3e3;
|
|
8059
|
+
var PROBE_RETRY_MS = 3e4;
|
|
8060
|
+
var HOST_TOKEN_ENV = "VIBEFLOW_HOST_TOKEN";
|
|
8061
|
+
function readInstalledVersion(packageRoot) {
|
|
8062
|
+
try {
|
|
8063
|
+
const pkg = JSON.parse(fs22.readFileSync(path26.join(packageRoot, "package.json"), "utf8"));
|
|
8064
|
+
return typeof pkg.version === "string" ? pkg.version : null;
|
|
8065
|
+
} catch {
|
|
8066
|
+
return null;
|
|
8067
|
+
}
|
|
8068
|
+
}
|
|
8069
|
+
async function probeCli(cliEntry) {
|
|
8070
|
+
try {
|
|
8071
|
+
const { stdout } = await execFileAsync2(process.execPath, [cliEntry, "--version"], { timeout: 15e3, windowsHide: true });
|
|
8072
|
+
return stdout.trim();
|
|
8073
|
+
} catch {
|
|
8074
|
+
return null;
|
|
8075
|
+
}
|
|
8076
|
+
}
|
|
8077
|
+
function watchInstalledVersion(options) {
|
|
8078
|
+
const readVersion2 = options.readVersion ?? readInstalledVersion;
|
|
8079
|
+
const probe = options.probe ?? probeCli;
|
|
8080
|
+
const now = options.now ?? Date.now;
|
|
8081
|
+
let previous = null;
|
|
8082
|
+
let installed = null;
|
|
8083
|
+
const probedAt = /* @__PURE__ */ new Map();
|
|
8084
|
+
let busy = false;
|
|
8085
|
+
const tick = async () => {
|
|
8086
|
+
if (busy) return;
|
|
8087
|
+
busy = true;
|
|
8088
|
+
try {
|
|
8089
|
+
const version = readVersion2(options.packageRoot);
|
|
8090
|
+
const seenTwice = version !== null && version === previous;
|
|
8091
|
+
previous = version;
|
|
8092
|
+
if (!version || !isNewerVersion(version, options.currentVersion)) return;
|
|
8093
|
+
if (installed !== version) {
|
|
8094
|
+
const last = probedAt.get(version);
|
|
8095
|
+
if (!seenTwice || last !== void 0 && now() - last < PROBE_RETRY_MS) return;
|
|
8096
|
+
probedAt.set(version, now());
|
|
8097
|
+
if (await probe(options.cliEntry) !== version) return;
|
|
8098
|
+
installed = version;
|
|
8099
|
+
}
|
|
8100
|
+
options.onInstalled(version);
|
|
8101
|
+
} finally {
|
|
8102
|
+
busy = false;
|
|
8103
|
+
}
|
|
8104
|
+
};
|
|
8105
|
+
return { tick };
|
|
8106
|
+
}
|
|
8107
|
+
function relaunchArgs(cliEntry, options) {
|
|
8108
|
+
return [cliEntry, "web", "--no-open", "--store-path", options.userDataDir, "--port", String(options.port), "--backend", options.backend];
|
|
8109
|
+
}
|
|
8110
|
+
function takeHandedOverToken(env = process.env) {
|
|
8111
|
+
const token = env[HOST_TOKEN_ENV];
|
|
8112
|
+
delete env[HOST_TOKEN_ENV];
|
|
8113
|
+
return token && /^[A-Za-z0-9_-]{43}$/.test(token) ? token : void 0;
|
|
8114
|
+
}
|
|
8115
|
+
|
|
8040
8116
|
// packages/cli/src/host.ts
|
|
8041
8117
|
var DEFAULT_HOST_PORT = 47820;
|
|
8042
8118
|
async function waitForPort(userDataDir, timeoutMs = 1e4) {
|
|
@@ -8060,7 +8136,7 @@ async function startHost(options) {
|
|
|
8060
8136
|
const lock = {
|
|
8061
8137
|
pid: process.pid,
|
|
8062
8138
|
port: 0,
|
|
8063
|
-
token: randomBytes2(32).toString("base64url"),
|
|
8139
|
+
token: options.token ?? randomBytes2(32).toString("base64url"),
|
|
8064
8140
|
version: options.version,
|
|
8065
8141
|
startedAt: Date.now()
|
|
8066
8142
|
};
|
|
@@ -8079,8 +8155,10 @@ async function startHost(options) {
|
|
|
8079
8155
|
});
|
|
8080
8156
|
const core = createCore({ sessions, bus, version: options.version });
|
|
8081
8157
|
let updateTimer = null;
|
|
8158
|
+
let installTimer = null;
|
|
8159
|
+
const packageRoot = options.cliEntry ? path27.dirname(path27.dirname(options.cliEntry)) : null;
|
|
8082
8160
|
const updates = createUpdateMonitor({
|
|
8083
|
-
packageName: options.sourceRoot || !
|
|
8161
|
+
packageName: options.sourceRoot || !packageRoot ? null : packageName(packageRoot),
|
|
8084
8162
|
currentVersion: options.version,
|
|
8085
8163
|
onChange: (update) => bus.emit("update:available", update)
|
|
8086
8164
|
});
|
|
@@ -8118,19 +8196,45 @@ async function startHost(options) {
|
|
|
8118
8196
|
updateLock(options.userDataDir, lock);
|
|
8119
8197
|
const stopWatch = core.watchStore();
|
|
8120
8198
|
core.warmModelCatalog();
|
|
8121
|
-
|
|
8199
|
+
let requestRestart = () => {
|
|
8200
|
+
};
|
|
8201
|
+
const restartRequested = new Promise((resolve) => {
|
|
8202
|
+
requestRestart = resolve;
|
|
8203
|
+
});
|
|
8204
|
+
if (updates.supported && options.cliEntry && packageRoot) {
|
|
8122
8205
|
checkUpdates();
|
|
8123
8206
|
updateTimer = setInterval(checkUpdates, UPDATE_CHECK_INTERVAL_MS);
|
|
8207
|
+
const installs = watchInstalledVersion({
|
|
8208
|
+
packageRoot,
|
|
8209
|
+
cliEntry: options.cliEntry,
|
|
8210
|
+
currentVersion: options.version,
|
|
8211
|
+
onInstalled: (version) => {
|
|
8212
|
+
if (!options.autoRestart) {
|
|
8213
|
+
updates.markInstalled(version, "\u7D42\u7AEF\u6A5F\u4ECB\u9762\uFF08TUI\uFF09host \u4E0D\u6703\u81EA\u52D5\u91CD\u65B0\u555F\u52D5");
|
|
8214
|
+
return;
|
|
8215
|
+
}
|
|
8216
|
+
void (sessions.kind === "pty" ? sessions.list() : Promise.resolve([])).then((running) => {
|
|
8217
|
+
if (running.length > 0) {
|
|
8218
|
+
updates.markInstalled(version, `\u6709 ${running.length} \u500B\u57F7\u884C\u4E2D\u7684\u7D42\u7AEF\u6A5F session\uFF0C\u91CD\u65B0\u555F\u52D5\u6703\u4E2D\u65B7\u5B83\u5011\uFF1B\u5168\u90E8\u7D50\u675F\u5F8C\u6703\u81EA\u52D5\u91CD\u65B0\u555F\u52D5`);
|
|
8219
|
+
} else {
|
|
8220
|
+
requestRestart(version);
|
|
8221
|
+
}
|
|
8222
|
+
}).catch(() => {
|
|
8223
|
+
});
|
|
8224
|
+
}
|
|
8225
|
+
});
|
|
8226
|
+
installTimer = setInterval(() => void installs.tick(), INSTALL_POLL_INTERVAL_MS);
|
|
8124
8227
|
}
|
|
8125
8228
|
const stop = () => stopping ??= (async () => {
|
|
8126
8229
|
updates.stop();
|
|
8127
8230
|
if (updateTimer) clearInterval(updateTimer);
|
|
8231
|
+
if (installTimer) clearInterval(installTimer);
|
|
8128
8232
|
stopWatch();
|
|
8129
8233
|
core.shutdown();
|
|
8130
8234
|
await server.close();
|
|
8131
8235
|
releaseLock(options.userDataDir);
|
|
8132
8236
|
})();
|
|
8133
|
-
return { kind: "started", host: { core, server, lock, stop } };
|
|
8237
|
+
return { kind: "started", host: { core, server, lock, restartRequested, stop } };
|
|
8134
8238
|
} catch (err) {
|
|
8135
8239
|
releaseLock(options.userDataDir);
|
|
8136
8240
|
throw err;
|
|
@@ -8140,7 +8244,7 @@ function loginUrl(lock, pathname = "/home/") {
|
|
|
8140
8244
|
return `http://127.0.0.1:${lock.port}${pathname}?token=${encodeURIComponent(lock.token)}`;
|
|
8141
8245
|
}
|
|
8142
8246
|
function isWebDir(dir) {
|
|
8143
|
-
return
|
|
8247
|
+
return fs23.existsSync(path27.join(dir, "home", "index.html"));
|
|
8144
8248
|
}
|
|
8145
8249
|
|
|
8146
8250
|
// packages/cli/src/remote.ts
|
|
@@ -8257,14 +8361,14 @@ function connectToHost(lock) {
|
|
|
8257
8361
|
}
|
|
8258
8362
|
|
|
8259
8363
|
// packages/cli/src/doctor.ts
|
|
8260
|
-
import
|
|
8261
|
-
import
|
|
8262
|
-
import { execFile as
|
|
8263
|
-
import { promisify as
|
|
8364
|
+
import fs24 from "fs";
|
|
8365
|
+
import path28 from "path";
|
|
8366
|
+
import { execFile as execFile11 } from "child_process";
|
|
8367
|
+
import { promisify as promisify8 } from "util";
|
|
8264
8368
|
init_env();
|
|
8265
8369
|
init_git_bash();
|
|
8266
8370
|
init_tmux_backend();
|
|
8267
|
-
var pexec6 =
|
|
8371
|
+
var pexec6 = promisify8(execFile11);
|
|
8268
8372
|
function parseVersion(text) {
|
|
8269
8373
|
const m = /(\d+)\.(\d+)(?:\.(\d+))?/.exec(text);
|
|
8270
8374
|
return m ? [Number(m[1]), Number(m[2]), Number(m[3] ?? 0)] : [];
|
|
@@ -8398,10 +8502,10 @@ async function runDoctor(options) {
|
|
|
8398
8502
|
});
|
|
8399
8503
|
}
|
|
8400
8504
|
try {
|
|
8401
|
-
|
|
8402
|
-
const probe =
|
|
8403
|
-
|
|
8404
|
-
|
|
8505
|
+
fs24.mkdirSync(options.userDataDir, { recursive: true });
|
|
8506
|
+
const probe = path28.join(options.userDataDir, `.doctor-${process.pid}`);
|
|
8507
|
+
fs24.writeFileSync(probe, "");
|
|
8508
|
+
fs24.rmSync(probe);
|
|
8405
8509
|
checks.push({ id: "data", name: "\u8CC7\u6599\u76EE\u9304", level: "ok", detail: options.userDataDir });
|
|
8406
8510
|
} catch (err) {
|
|
8407
8511
|
checks.push({
|
|
@@ -8441,7 +8545,7 @@ Usage:
|
|
|
8441
8545
|
vibeflow open <path> Add a project folder to the recent list, then open the Web UI
|
|
8442
8546
|
vibeflow doctor Check Node, git, tmux, node-pty and the agent CLIs
|
|
8443
8547
|
(--skip agents,web,\u2026 leaves checks out, e.g. on CI)
|
|
8444
|
-
vibeflow update Install the latest global npm release (
|
|
8548
|
+
vibeflow update Install the latest global npm release (a running Web UI host restarts into it)
|
|
8445
8549
|
vibeflow task \u2026 Create / update cards; add artifacts (vibeflow task --help)
|
|
8446
8550
|
|
|
8447
8551
|
Options:
|
|
@@ -8456,24 +8560,24 @@ Options:
|
|
|
8456
8560
|
`.trim();
|
|
8457
8561
|
function detectLayout() {
|
|
8458
8562
|
const file = fileURLToPath(import.meta.url);
|
|
8459
|
-
const here =
|
|
8460
|
-
const bundledWeb =
|
|
8461
|
-
if (isWebDir(bundledWeb) ||
|
|
8563
|
+
const here = path31.dirname(file);
|
|
8564
|
+
const bundledWeb = path31.join(here, "web");
|
|
8565
|
+
if (isWebDir(bundledWeb) || path31.basename(here) === "dist") {
|
|
8462
8566
|
return {
|
|
8463
|
-
version: readVersion(
|
|
8567
|
+
version: readVersion(path31.join(here, "..", "package.json")),
|
|
8464
8568
|
webDir: isWebDir(bundledWeb) ? bundledWeb : null,
|
|
8465
8569
|
sourceRoot: null,
|
|
8466
8570
|
cliEntry: file
|
|
8467
8571
|
};
|
|
8468
8572
|
}
|
|
8469
|
-
const root =
|
|
8573
|
+
const root = path31.resolve(here, "..", "..", "..");
|
|
8470
8574
|
const override = process.env.VIBEFLOW_WEB_DIR;
|
|
8471
|
-
const webDir = override && isWebDir(override) ? override : isWebDir(
|
|
8472
|
-
return { version: readVersion(
|
|
8575
|
+
const webDir = override && isWebDir(override) ? override : isWebDir(path31.join(root, "app")) ? path31.join(root, "app") : null;
|
|
8576
|
+
return { version: readVersion(path31.join(root, "package.json")), webDir, sourceRoot: root, cliEntry: null };
|
|
8473
8577
|
}
|
|
8474
8578
|
function readVersion(pkgPath) {
|
|
8475
8579
|
try {
|
|
8476
|
-
return JSON.parse(
|
|
8580
|
+
return JSON.parse(fs26.readFileSync(pkgPath, "utf8")).version;
|
|
8477
8581
|
} catch {
|
|
8478
8582
|
return "0.0.0";
|
|
8479
8583
|
}
|
|
@@ -8497,6 +8601,7 @@ function parse(argv) {
|
|
|
8497
8601
|
strict: true
|
|
8498
8602
|
});
|
|
8499
8603
|
}
|
|
8604
|
+
var handedOverToken = takeHandedOverToken();
|
|
8500
8605
|
function hostOptions(values, layout, userDataDir, withWeb = true) {
|
|
8501
8606
|
const backend = values.backend ?? "auto";
|
|
8502
8607
|
if (!["auto", "tmux", "pty"].includes(backend)) throw new Error("--backend must be auto | tmux | pty");
|
|
@@ -8509,7 +8614,8 @@ function hostOptions(values, layout, userDataDir, withWeb = true) {
|
|
|
8509
8614
|
sourceRoot: layout.sourceRoot,
|
|
8510
8615
|
cliEntry: layout.cliEntry,
|
|
8511
8616
|
backend,
|
|
8512
|
-
port
|
|
8617
|
+
port,
|
|
8618
|
+
token: handedOverToken
|
|
8513
8619
|
};
|
|
8514
8620
|
}
|
|
8515
8621
|
async function openBrowser(url) {
|
|
@@ -8518,6 +8624,33 @@ async function openBrowser(url) {
|
|
|
8518
8624
|
} catch {
|
|
8519
8625
|
}
|
|
8520
8626
|
}
|
|
8627
|
+
async function relaunchHost(host, cliEntry, userDataDir, version) {
|
|
8628
|
+
const port = host.lock.port;
|
|
8629
|
+
const token = host.lock.token;
|
|
8630
|
+
const backend = host.core.sessions.kind;
|
|
8631
|
+
console.log(`
|
|
8632
|
+
\u5DF2\u5B89\u88DD VibeFlow ${version}\uFF0C\u6B63\u5728\u91CD\u65B0\u555F\u52D5 host\u2026`);
|
|
8633
|
+
await host.stop();
|
|
8634
|
+
const child = spawn9(process.execPath, relaunchArgs(cliEntry, { userDataDir, port, backend }), {
|
|
8635
|
+
stdio: "inherit",
|
|
8636
|
+
env: { ...process.env, [HOST_TOKEN_ENV]: token }
|
|
8637
|
+
});
|
|
8638
|
+
const forward = () => {
|
|
8639
|
+
child.kill("SIGTERM");
|
|
8640
|
+
};
|
|
8641
|
+
process.on("SIGINT", () => {
|
|
8642
|
+
});
|
|
8643
|
+
process.on("SIGHUP", () => {
|
|
8644
|
+
});
|
|
8645
|
+
process.on("SIGTERM", forward);
|
|
8646
|
+
return new Promise((resolve) => {
|
|
8647
|
+
child.once("error", (err) => {
|
|
8648
|
+
console.error(`\u7121\u6CD5\u555F\u52D5\u65B0\u7248 host\uFF1A${err.message}\u3002\u8ACB\u57F7\u884C vibeflow \u91CD\u65B0\u555F\u52D5\u3002`);
|
|
8649
|
+
resolve(1);
|
|
8650
|
+
});
|
|
8651
|
+
child.once("exit", (code2, signal) => resolve(code2 ?? (signal ? 1 : 0)));
|
|
8652
|
+
});
|
|
8653
|
+
}
|
|
8521
8654
|
function stopOnSignals(host) {
|
|
8522
8655
|
return new Promise((resolve) => {
|
|
8523
8656
|
const stop = () => {
|
|
@@ -8540,7 +8673,7 @@ async function cmdWeb(values, layout, userDataDir, pathname = "/home/") {
|
|
|
8540
8673
|
console.error("\u627E\u4E0D\u5230 Web UI \u7684\u975C\u614B\u6A94\u3002\u5F9E\u539F\u59CB\u78BC\u57F7\u884C\u6642\u8ACB\u5148\u57F7\u884C\uFF1Anpm run build:web");
|
|
8541
8674
|
return 1;
|
|
8542
8675
|
}
|
|
8543
|
-
const started = await startHost(hostOptions(values, layout, userDataDir));
|
|
8676
|
+
const started = await startHost({ ...hostOptions(values, layout, userDataDir), autoRestart: true });
|
|
8544
8677
|
if (started.kind === "running") return cmdWeb(values, layout, userDataDir, pathname);
|
|
8545
8678
|
const { host } = started;
|
|
8546
8679
|
const url = loginUrl(host.lock, pathname);
|
|
@@ -8553,8 +8686,11 @@ async function cmdWeb(values, layout, userDataDir, pathname = "/home/") {
|
|
|
8553
8686
|
${formatChecks(checks)}
|
|
8554
8687
|
`);
|
|
8555
8688
|
if (!values["no-open"]) await openBrowser(url);
|
|
8556
|
-
await
|
|
8557
|
-
|
|
8689
|
+
const ended = await Promise.race([
|
|
8690
|
+
stopOnSignals(host).then(() => null),
|
|
8691
|
+
host.restartRequested
|
|
8692
|
+
]);
|
|
8693
|
+
return ended === null || !layout.cliEntry ? 0 : relaunchHost(host, layout.cliEntry, userDataDir, ended);
|
|
8558
8694
|
}
|
|
8559
8695
|
async function cmdTui(values, layout, userDataDir) {
|
|
8560
8696
|
const { runTui: runTui2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
@@ -8679,8 +8815,8 @@ async function cmdOpen(values, target, layout, userDataDir) {
|
|
|
8679
8815
|
console.error("\u7528\u6CD5\uFF1Avibeflow open <path>");
|
|
8680
8816
|
return 1;
|
|
8681
8817
|
}
|
|
8682
|
-
const dir =
|
|
8683
|
-
if (!
|
|
8818
|
+
const dir = path31.resolve(target);
|
|
8819
|
+
if (!fs26.existsSync(dir) || !fs26.statSync(dir).isDirectory()) {
|
|
8684
8820
|
console.error(`\u4E0D\u662F\u8CC7\u6599\u593E\uFF1A${dir}`);
|
|
8685
8821
|
return 1;
|
|
8686
8822
|
}
|
package/dist/web/404/index.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/3cafb8bddc730b60.css" as="style"/><link rel="stylesheet" href="/_next/static/css/3cafb8bddc730b60.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/3cafb8bddc730b60.css" as="style"/><link rel="stylesheet" href="/_next/static/css/3cafb8bddc730b60.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-2571a2564f593899.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/wiyRNf4HeW4AW-LhhYSsf/_buildManifest.js" defer=""></script><script src="/_next/static/wiyRNf4HeW4AW-LhhYSsf/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"wiyRNf4HeW4AW-LhhYSsf","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
package/dist/web/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/3cafb8bddc730b60.css" as="style"/><link rel="stylesheet" href="/_next/static/css/3cafb8bddc730b60.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/3cafb8bddc730b60.css" as="style"/><link rel="stylesheet" href="/_next/static/css/3cafb8bddc730b60.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-2571a2564f593899.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/wiyRNf4HeW4AW-LhhYSsf/_buildManifest.js" defer=""></script><script src="/_next/static/wiyRNf4HeW4AW-LhhYSsf/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"wiyRNf4HeW4AW-LhhYSsf","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|