@kw-yeh/vibeflow 4.11.1 → 4.11.3
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/README.md +2 -0
- package/dist/vibeflow.mjs +162 -74
- package/dist/web/404/index.html +1 -1
- package/dist/web/404.html +1 -1
- package/dist/web/_next/static/chunks/pages/{_app-ab090e0b95efc7ae.js → _app-70ce066e3ac8e039.js} +1 -1
- package/dist/web/_next/static/chunks/pages/home-82b9b5d7e210320a.js +13 -0
- package/dist/web/_next/static/css/9b4fcf22ca8f6bc9.css +2 -0
- package/dist/web/_next/static/{sVCe3iO4fTLCxTOdzqdP8 → sZPeIltIrJDddiLXt5zx1}/_buildManifest.js +1 -1
- package/dist/web/home/index.html +1 -1
- package/package.json +1 -1
- package/dist/web/_next/static/chunks/pages/home-dd9e0926a5988575.js +0 -12
- package/dist/web/_next/static/css/9d4fa221b4133d92.css +0 -2
- /package/dist/web/_next/static/{sVCe3iO4fTLCxTOdzqdP8 → sZPeIltIrJDddiLXt5zx1}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -91,6 +91,8 @@ vibeflow update
|
|
|
91
91
|
|
|
92
92
|
更新完成後,若 VibeFlow 正在執行,請自行關閉並重新啟動 host,才會載入新版。此指令只適用於全域 npm 安裝;從原始碼、`npx` 或專案本地安裝執行時不會更動套件。
|
|
93
93
|
|
|
94
|
+
以 npm 套件執行時,VibeFlow 啟動後及每兩小時會檢查 npm 是否有新版;有新版會在看板上方提示。**設定** 視窗會顯示目前執行中的版本。從原始碼執行時只顯示版本,不查 npm 更新。
|
|
95
|
+
|
|
94
96
|
### 安裝時出現 `EACCES: permission denied`
|
|
95
97
|
|
|
96
98
|
代表 npm 的全域目錄屬於系統管理員(從 nodejs.org 下載安裝檔裝 Node 時常見)。建議不要用 `sudo`,改成讓全域套件裝在你自己的家目錄:
|
package/dist/vibeflow.mjs
CHANGED
|
@@ -257,6 +257,9 @@ var init_pty = __esm({
|
|
|
257
257
|
scrollback(key) {
|
|
258
258
|
return this.scrollbacks.get(key) ?? null;
|
|
259
259
|
}
|
|
260
|
+
discardScrollback(key) {
|
|
261
|
+
this.scrollbacks.delete(key);
|
|
262
|
+
}
|
|
260
263
|
async isScrolledBack() {
|
|
261
264
|
return false;
|
|
262
265
|
}
|
|
@@ -2448,6 +2451,8 @@ function createBridge(t) {
|
|
|
2448
2451
|
getState: () => t.invoke("vibeflow:getState"),
|
|
2449
2452
|
/** Running app version (package.json version baked into the build). */
|
|
2450
2453
|
getVersion: () => t.invoke("app:getVersion"),
|
|
2454
|
+
getUpdateStatus: () => t.invoke("host:updateStatus"),
|
|
2455
|
+
onUpdateAvailable: (callback) => t.on("update:available", (payload) => callback(payload)),
|
|
2451
2456
|
/**
|
|
2452
2457
|
* Fired when an external write (e.g. CLI) changes the store backing file.
|
|
2453
2458
|
* The main process debounces and emits the fresh state so the board can
|
|
@@ -2574,6 +2579,7 @@ function createBridge(t) {
|
|
|
2574
2579
|
* `sessionKey` defaults to `taskId`.
|
|
2575
2580
|
*/
|
|
2576
2581
|
start: (payload) => t.invoke("pty:start", payload),
|
|
2582
|
+
startStandalone: (payload) => t.invoke("terminal:start", payload),
|
|
2577
2583
|
/** Join a running session without restarting it. */
|
|
2578
2584
|
peek: (sessionKey) => t.invoke("pty:peek", sessionKey),
|
|
2579
2585
|
/** Which session backend runs terminals, and the sessions it has running. */
|
|
@@ -4632,8 +4638,8 @@ async function taskCommand(argv) {
|
|
|
4632
4638
|
}
|
|
4633
4639
|
|
|
4634
4640
|
// packages/cli/src/host.ts
|
|
4635
|
-
import
|
|
4636
|
-
import
|
|
4641
|
+
import fs21 from "fs";
|
|
4642
|
+
import path25 from "path";
|
|
4637
4643
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
4638
4644
|
|
|
4639
4645
|
// packages/core/src/events.ts
|
|
@@ -6784,6 +6790,7 @@ function validBoard(value) {
|
|
|
6784
6790
|
function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatus, acliRunner, jiraAuthStatus, modelCatalog }) {
|
|
6785
6791
|
const sink = bus.sink();
|
|
6786
6792
|
const models = modelCatalog ?? createModelCatalog({ version });
|
|
6793
|
+
const standaloneTerminals = /* @__PURE__ */ new Map();
|
|
6787
6794
|
let libraryCodexHome = null;
|
|
6788
6795
|
void libraryRoot().then((root) => {
|
|
6789
6796
|
libraryCodexHome = libraryPaths(root).codexHome;
|
|
@@ -6838,7 +6845,10 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
6838
6845
|
} catch {
|
|
6839
6846
|
}
|
|
6840
6847
|
async function teardownSession(key) {
|
|
6848
|
+
const standalone = standaloneTerminals.has(key);
|
|
6841
6849
|
await sessions.kill(key);
|
|
6850
|
+
if (standalone) sessions.discardScrollback?.(key);
|
|
6851
|
+
standaloneTerminals.delete(key);
|
|
6842
6852
|
unwatchSubAgents(key);
|
|
6843
6853
|
}
|
|
6844
6854
|
async function teardownTask(taskId) {
|
|
@@ -6853,6 +6863,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
6853
6863
|
}
|
|
6854
6864
|
function requireSessionKey(sessionKey) {
|
|
6855
6865
|
const key = str(sessionKey, "sessionKey");
|
|
6866
|
+
if (standaloneTerminals.has(key)) return key;
|
|
6856
6867
|
requireTask(key.split(":")[0]);
|
|
6857
6868
|
return key;
|
|
6858
6869
|
}
|
|
@@ -7188,6 +7199,26 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
7188
7199
|
}
|
|
7189
7200
|
return result;
|
|
7190
7201
|
},
|
|
7202
|
+
"terminal:start": async (payload) => {
|
|
7203
|
+
const p = obj(payload, "payload");
|
|
7204
|
+
const key = str(p.sessionKey, "sessionKey");
|
|
7205
|
+
if (!/^terminal_[0-9a-f-]{36}$/.test(key)) invalid("invalid standalone terminal key");
|
|
7206
|
+
if (Boolean(p.taskId) === Boolean(p.projectPath)) invalid("provide taskId or projectPath");
|
|
7207
|
+
const cwd = str(p.taskId ? requireTask(p.taskId).projectPath : p.projectPath, "projectPath");
|
|
7208
|
+
if (!path22.isAbsolute(cwd) || !fs18.existsSync(cwd) || !fs18.statSync(cwd).isDirectory()) {
|
|
7209
|
+
invalid("projectPath must be an existing absolute directory");
|
|
7210
|
+
}
|
|
7211
|
+
const previous = standaloneTerminals.get(key);
|
|
7212
|
+
if (previous && previous !== cwd) invalid("terminal key already belongs to another directory");
|
|
7213
|
+
const result = await sessions.start(key, {
|
|
7214
|
+
cwd,
|
|
7215
|
+
cols: typeof p.cols === "number" ? p.cols : void 0,
|
|
7216
|
+
rows: typeof p.rows === "number" ? p.rows : void 0
|
|
7217
|
+
});
|
|
7218
|
+
standaloneTerminals.set(key, cwd);
|
|
7219
|
+
if (!p.taskId) recordRecentProject(getStore(), cwd);
|
|
7220
|
+
return result;
|
|
7221
|
+
},
|
|
7191
7222
|
// Join a session as it is: no restart, for a frontend that attaches
|
|
7192
7223
|
// after it started (the TUI's terminal view).
|
|
7193
7224
|
"pty:peek": async (sessionKey) => {
|
|
@@ -7720,6 +7751,101 @@ Content-Length: 0\r
|
|
|
7720
7751
|
};
|
|
7721
7752
|
}
|
|
7722
7753
|
|
|
7754
|
+
// packages/cli/src/update-command.ts
|
|
7755
|
+
import fs20 from "node:fs";
|
|
7756
|
+
import path24 from "node:path";
|
|
7757
|
+
import { spawnSync } from "node:child_process";
|
|
7758
|
+
function npmRunner(args, inherit) {
|
|
7759
|
+
const windows = process.platform === "win32";
|
|
7760
|
+
return spawnSync(windows ? "npm.cmd" : "npm", args, {
|
|
7761
|
+
encoding: "utf8",
|
|
7762
|
+
stdio: inherit ? "inherit" : ["ignore", "pipe", "inherit"],
|
|
7763
|
+
windowsHide: true,
|
|
7764
|
+
shell: windows
|
|
7765
|
+
});
|
|
7766
|
+
}
|
|
7767
|
+
function packageName(packageRoot) {
|
|
7768
|
+
try {
|
|
7769
|
+
const pkg = JSON.parse(fs20.readFileSync(path24.join(packageRoot, "package.json"), "utf8"));
|
|
7770
|
+
if (typeof pkg.name !== "string") return null;
|
|
7771
|
+
return /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(pkg.name) ? pkg.name : null;
|
|
7772
|
+
} catch {
|
|
7773
|
+
return null;
|
|
7774
|
+
}
|
|
7775
|
+
}
|
|
7776
|
+
function runUpdate(options) {
|
|
7777
|
+
const log = options.log ?? console.log;
|
|
7778
|
+
const error = options.error ?? console.error;
|
|
7779
|
+
const runNpm = options.runNpm ?? npmRunner;
|
|
7780
|
+
if (options.sourceRoot || !options.cliEntry) {
|
|
7781
|
+
error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u662F\u539F\u59CB\u78BC\u7248\u672C\u3002");
|
|
7782
|
+
return 1;
|
|
7783
|
+
}
|
|
7784
|
+
const packageRoot = path24.dirname(path24.dirname(options.cliEntry));
|
|
7785
|
+
const name = packageName(packageRoot);
|
|
7786
|
+
if (!name) {
|
|
7787
|
+
error("\u7121\u6CD5\u8FA8\u8B58\u76EE\u524D VibeFlow \u7684 npm \u5957\u4EF6\u540D\u7A31\uFF0C\u5DF2\u53D6\u6D88\u66F4\u65B0\u3002");
|
|
7788
|
+
return 1;
|
|
7789
|
+
}
|
|
7790
|
+
const root = runNpm(["root", "-g"], false);
|
|
7791
|
+
if (root.error || root.status !== 0 || !String(root.stdout ?? "").trim()) {
|
|
7792
|
+
error(`\u7121\u6CD5\u67E5\u8A62 npm \u5168\u57DF\u5B89\u88DD\u76EE\u9304\uFF1A${root.error?.message ?? `npm \u7D50\u675F\u78BC ${root.status ?? "unknown"}`}`);
|
|
7793
|
+
return 1;
|
|
7794
|
+
}
|
|
7795
|
+
try {
|
|
7796
|
+
const globalPackage = path24.join(String(root.stdout).trim(), ...name.split("/"));
|
|
7797
|
+
if (fs20.lstatSync(globalPackage).isSymbolicLink() || fs20.realpathSync(globalPackage) !== fs20.realpathSync(packageRoot)) {
|
|
7798
|
+
error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4F86\u81EA\u5176\u4ED6\u4F4D\u7F6E\u3002");
|
|
7799
|
+
return 1;
|
|
7800
|
+
}
|
|
7801
|
+
} catch {
|
|
7802
|
+
error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4E0D\u662F npm \u5168\u57DF\u5B89\u88DD\u3002");
|
|
7803
|
+
return 1;
|
|
7804
|
+
}
|
|
7805
|
+
log(`\u6B63\u5728\u66F4\u65B0 ${name} \u81F3 npm latest\u2026`);
|
|
7806
|
+
const result = runNpm(["install", "-g", `${name}@latest`], true);
|
|
7807
|
+
if (result.error || result.status !== 0) {
|
|
7808
|
+
error(`\u66F4\u65B0\u5931\u6557\uFF1A${result.error?.message ?? `npm \u7D50\u675F\u78BC ${result.status ?? "unknown"}`}`);
|
|
7809
|
+
return result.status && result.status > 0 ? result.status : 1;
|
|
7810
|
+
}
|
|
7811
|
+
log("\u66F4\u65B0\u5B8C\u6210\u3002\u82E5 VibeFlow host \u6B63\u5728\u57F7\u884C\uFF0C\u8ACB\u81EA\u884C\u91CD\u65B0\u555F\u52D5\u4EE5\u8F09\u5165\u65B0\u7248\u672C\u3002");
|
|
7812
|
+
return 0;
|
|
7813
|
+
}
|
|
7814
|
+
|
|
7815
|
+
// packages/cli/src/update-check.ts
|
|
7816
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
7817
|
+
import { promisify as promisify6 } from "node:util";
|
|
7818
|
+
var execFileAsync = promisify6(execFile9);
|
|
7819
|
+
var UPDATE_CHECK_INTERVAL_MS = 2 * 60 * 60 * 1e3;
|
|
7820
|
+
function versionParts(value) {
|
|
7821
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(value);
|
|
7822
|
+
if (!match) return null;
|
|
7823
|
+
return { numbers: match.slice(1, 4).map(Number), prerelease: !!match[4] };
|
|
7824
|
+
}
|
|
7825
|
+
function isNewerVersion(latest, current) {
|
|
7826
|
+
const next = versionParts(latest);
|
|
7827
|
+
const installed = versionParts(current);
|
|
7828
|
+
if (!next || !installed) return false;
|
|
7829
|
+
for (let index = 0; index < 3; index++) {
|
|
7830
|
+
if (next.numbers[index] !== installed.numbers[index]) {
|
|
7831
|
+
return next.numbers[index] > installed.numbers[index];
|
|
7832
|
+
}
|
|
7833
|
+
}
|
|
7834
|
+
return installed.prerelease && !next.prerelease;
|
|
7835
|
+
}
|
|
7836
|
+
async function checkForUpdate(packageName2, currentVersion, query = async (name) => {
|
|
7837
|
+
const { stdout } = await execFileAsync(
|
|
7838
|
+
process.platform === "win32" ? "npm.cmd" : "npm",
|
|
7839
|
+
["view", `${name}@latest`, "version", "--json"],
|
|
7840
|
+
{ timeout: 1e4, windowsHide: true, shell: process.platform === "win32" }
|
|
7841
|
+
);
|
|
7842
|
+
return stdout;
|
|
7843
|
+
}) {
|
|
7844
|
+
const latest = JSON.parse(await query(packageName2));
|
|
7845
|
+
if (typeof latest !== "string" || !isNewerVersion(latest, currentVersion)) return null;
|
|
7846
|
+
return { currentVersion, latestVersion: latest };
|
|
7847
|
+
}
|
|
7848
|
+
|
|
7723
7849
|
// packages/cli/src/host.ts
|
|
7724
7850
|
var DEFAULT_HOST_PORT = 47820;
|
|
7725
7851
|
async function waitForPort(userDataDir, timeoutMs = 1e4) {
|
|
@@ -7761,6 +7887,22 @@ async function startHost(options) {
|
|
|
7761
7887
|
stateDir: options.userDataDir
|
|
7762
7888
|
});
|
|
7763
7889
|
const core = createCore({ sessions, bus, version: options.version });
|
|
7890
|
+
let availableUpdate = null;
|
|
7891
|
+
let updateTimer = null;
|
|
7892
|
+
let stopped = false;
|
|
7893
|
+
const installedPackage = options.sourceRoot || !options.cliEntry ? null : packageName(path25.dirname(path25.dirname(options.cliEntry)));
|
|
7894
|
+
const checkUpdates = async () => {
|
|
7895
|
+
if (!installedPackage) return;
|
|
7896
|
+
try {
|
|
7897
|
+
const next = await checkForUpdate(installedPackage, options.version);
|
|
7898
|
+
if (stopped) return;
|
|
7899
|
+
if (next?.latestVersion !== availableUpdate?.latestVersion) {
|
|
7900
|
+
availableUpdate = next;
|
|
7901
|
+
bus.emit("update:available", next);
|
|
7902
|
+
}
|
|
7903
|
+
} catch {
|
|
7904
|
+
}
|
|
7905
|
+
};
|
|
7764
7906
|
let stopping = null;
|
|
7765
7907
|
const handlers = {
|
|
7766
7908
|
...core.handlers,
|
|
@@ -7773,7 +7915,8 @@ async function startHost(options) {
|
|
|
7773
7915
|
version: options.version,
|
|
7774
7916
|
backend: sessions.kind,
|
|
7775
7917
|
startedAt: lock.startedAt
|
|
7776
|
-
})
|
|
7918
|
+
}),
|
|
7919
|
+
"host:updateStatus": () => availableUpdate
|
|
7777
7920
|
};
|
|
7778
7921
|
const server = await startWebServer({
|
|
7779
7922
|
handlers,
|
|
@@ -7787,7 +7930,13 @@ async function startHost(options) {
|
|
|
7787
7930
|
updateLock(options.userDataDir, lock);
|
|
7788
7931
|
const stopWatch = core.watchStore();
|
|
7789
7932
|
core.warmModelCatalog();
|
|
7933
|
+
if (installedPackage) {
|
|
7934
|
+
void checkUpdates();
|
|
7935
|
+
updateTimer = setInterval(() => void checkUpdates(), UPDATE_CHECK_INTERVAL_MS);
|
|
7936
|
+
}
|
|
7790
7937
|
const stop = () => stopping ??= (async () => {
|
|
7938
|
+
stopped = true;
|
|
7939
|
+
if (updateTimer) clearInterval(updateTimer);
|
|
7791
7940
|
stopWatch();
|
|
7792
7941
|
core.shutdown();
|
|
7793
7942
|
await server.close();
|
|
@@ -7803,7 +7952,7 @@ function loginUrl(lock, pathname = "/home/") {
|
|
|
7803
7952
|
return `http://127.0.0.1:${lock.port}${pathname}?token=${encodeURIComponent(lock.token)}`;
|
|
7804
7953
|
}
|
|
7805
7954
|
function isWebDir(dir) {
|
|
7806
|
-
return
|
|
7955
|
+
return fs21.existsSync(path25.join(dir, "home", "index.html"));
|
|
7807
7956
|
}
|
|
7808
7957
|
|
|
7809
7958
|
// packages/cli/src/remote.ts
|
|
@@ -7920,14 +8069,14 @@ function connectToHost(lock) {
|
|
|
7920
8069
|
}
|
|
7921
8070
|
|
|
7922
8071
|
// packages/cli/src/doctor.ts
|
|
7923
|
-
import
|
|
7924
|
-
import
|
|
7925
|
-
import { execFile as
|
|
7926
|
-
import { promisify as
|
|
8072
|
+
import fs22 from "fs";
|
|
8073
|
+
import path26 from "path";
|
|
8074
|
+
import { execFile as execFile10 } from "child_process";
|
|
8075
|
+
import { promisify as promisify7 } from "util";
|
|
7927
8076
|
init_env();
|
|
7928
8077
|
init_git_bash();
|
|
7929
8078
|
init_tmux_backend();
|
|
7930
|
-
var pexec6 =
|
|
8079
|
+
var pexec6 = promisify7(execFile10);
|
|
7931
8080
|
function parseVersion(text) {
|
|
7932
8081
|
const m = /(\d+)\.(\d+)(?:\.(\d+))?/.exec(text);
|
|
7933
8082
|
return m ? [Number(m[1]), Number(m[2]), Number(m[3] ?? 0)] : [];
|
|
@@ -8061,10 +8210,10 @@ async function runDoctor(options) {
|
|
|
8061
8210
|
});
|
|
8062
8211
|
}
|
|
8063
8212
|
try {
|
|
8064
|
-
|
|
8065
|
-
const probe =
|
|
8066
|
-
|
|
8067
|
-
|
|
8213
|
+
fs22.mkdirSync(options.userDataDir, { recursive: true });
|
|
8214
|
+
const probe = path26.join(options.userDataDir, `.doctor-${process.pid}`);
|
|
8215
|
+
fs22.writeFileSync(probe, "");
|
|
8216
|
+
fs22.rmSync(probe);
|
|
8068
8217
|
checks.push({ id: "data", name: "\u8CC7\u6599\u76EE\u9304", level: "ok", detail: options.userDataDir });
|
|
8069
8218
|
} catch (err) {
|
|
8070
8219
|
checks.push({
|
|
@@ -8090,67 +8239,6 @@ function formatChecks(checks) {
|
|
|
8090
8239
|
return lines.join("\n");
|
|
8091
8240
|
}
|
|
8092
8241
|
|
|
8093
|
-
// packages/cli/src/update-command.ts
|
|
8094
|
-
import fs22 from "node:fs";
|
|
8095
|
-
import path26 from "node:path";
|
|
8096
|
-
import { spawnSync } from "node:child_process";
|
|
8097
|
-
function npmRunner(args, inherit) {
|
|
8098
|
-
const windows = process.platform === "win32";
|
|
8099
|
-
return spawnSync(windows ? "npm.cmd" : "npm", args, {
|
|
8100
|
-
encoding: "utf8",
|
|
8101
|
-
stdio: inherit ? "inherit" : ["ignore", "pipe", "inherit"],
|
|
8102
|
-
windowsHide: true,
|
|
8103
|
-
shell: windows
|
|
8104
|
-
});
|
|
8105
|
-
}
|
|
8106
|
-
function packageName(packageRoot) {
|
|
8107
|
-
try {
|
|
8108
|
-
const pkg = JSON.parse(fs22.readFileSync(path26.join(packageRoot, "package.json"), "utf8"));
|
|
8109
|
-
if (typeof pkg.name !== "string") return null;
|
|
8110
|
-
return /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(pkg.name) ? pkg.name : null;
|
|
8111
|
-
} catch {
|
|
8112
|
-
return null;
|
|
8113
|
-
}
|
|
8114
|
-
}
|
|
8115
|
-
function runUpdate(options) {
|
|
8116
|
-
const log = options.log ?? console.log;
|
|
8117
|
-
const error = options.error ?? console.error;
|
|
8118
|
-
const runNpm = options.runNpm ?? npmRunner;
|
|
8119
|
-
if (options.sourceRoot || !options.cliEntry) {
|
|
8120
|
-
error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u662F\u539F\u59CB\u78BC\u7248\u672C\u3002");
|
|
8121
|
-
return 1;
|
|
8122
|
-
}
|
|
8123
|
-
const packageRoot = path26.dirname(path26.dirname(options.cliEntry));
|
|
8124
|
-
const name = packageName(packageRoot);
|
|
8125
|
-
if (!name) {
|
|
8126
|
-
error("\u7121\u6CD5\u8FA8\u8B58\u76EE\u524D VibeFlow \u7684 npm \u5957\u4EF6\u540D\u7A31\uFF0C\u5DF2\u53D6\u6D88\u66F4\u65B0\u3002");
|
|
8127
|
-
return 1;
|
|
8128
|
-
}
|
|
8129
|
-
const root = runNpm(["root", "-g"], false);
|
|
8130
|
-
if (root.error || root.status !== 0 || !String(root.stdout ?? "").trim()) {
|
|
8131
|
-
error(`\u7121\u6CD5\u67E5\u8A62 npm \u5168\u57DF\u5B89\u88DD\u76EE\u9304\uFF1A${root.error?.message ?? `npm \u7D50\u675F\u78BC ${root.status ?? "unknown"}`}`);
|
|
8132
|
-
return 1;
|
|
8133
|
-
}
|
|
8134
|
-
try {
|
|
8135
|
-
const globalPackage = path26.join(String(root.stdout).trim(), ...name.split("/"));
|
|
8136
|
-
if (fs22.lstatSync(globalPackage).isSymbolicLink() || fs22.realpathSync(globalPackage) !== fs22.realpathSync(packageRoot)) {
|
|
8137
|
-
error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4F86\u81EA\u5176\u4ED6\u4F4D\u7F6E\u3002");
|
|
8138
|
-
return 1;
|
|
8139
|
-
}
|
|
8140
|
-
} catch {
|
|
8141
|
-
error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4E0D\u662F npm \u5168\u57DF\u5B89\u88DD\u3002");
|
|
8142
|
-
return 1;
|
|
8143
|
-
}
|
|
8144
|
-
log(`\u6B63\u5728\u66F4\u65B0 ${name} \u81F3 npm latest\u2026`);
|
|
8145
|
-
const result = runNpm(["install", "-g", `${name}@latest`], true);
|
|
8146
|
-
if (result.error || result.status !== 0) {
|
|
8147
|
-
error(`\u66F4\u65B0\u5931\u6557\uFF1A${result.error?.message ?? `npm \u7D50\u675F\u78BC ${result.status ?? "unknown"}`}`);
|
|
8148
|
-
return result.status && result.status > 0 ? result.status : 1;
|
|
8149
|
-
}
|
|
8150
|
-
log("\u66F4\u65B0\u5B8C\u6210\u3002\u82E5 VibeFlow host \u6B63\u5728\u57F7\u884C\uFF0C\u8ACB\u81EA\u884C\u91CD\u65B0\u555F\u52D5\u4EE5\u8F09\u5165\u65B0\u7248\u672C\u3002");
|
|
8151
|
-
return 0;
|
|
8152
|
-
}
|
|
8153
|
-
|
|
8154
8242
|
// packages/cli/src/main.ts
|
|
8155
8243
|
var USAGE = `
|
|
8156
8244
|
VibeFlow \u2014 intent-driven kanban for coding agents
|
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/
|
|
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/9b4fcf22ca8f6bc9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/9b4fcf22ca8f6bc9.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-70ce066e3ac8e039.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_buildManifest.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_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":"sZPeIltIrJDddiLXt5zx1","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/
|
|
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/9b4fcf22ca8f6bc9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/9b4fcf22ca8f6bc9.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-70ce066e3ac8e039.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_buildManifest.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_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":"sZPeIltIrJDddiLXt5zx1","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|