@kw-yeh/vibeflow 4.11.24 → 4.11.25
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 +196 -178
- package/dist/web/404/index.html +1 -1
- package/dist/web/404.html +1 -1
- package/dist/web/home/index.html +1 -1
- package/package.json +1 -1
- /package/dist/web/_next/static/{2-gox_m7xBQBsIihLK8dE → wK5QA4FEMxOvUUnrrWMLN}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{2-gox_m7xBQBsIihLK8dE → wK5QA4FEMxOvUUnrrWMLN}/_ssgManifest.js +0 -0
package/dist/vibeflow.mjs
CHANGED
|
@@ -17,6 +17,7 @@ var __export = (target, all) => {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
// packages/core/src/env.ts
|
|
20
|
+
import fs3 from "fs";
|
|
20
21
|
import os from "os";
|
|
21
22
|
import path5 from "path";
|
|
22
23
|
function buildEnv() {
|
|
@@ -75,6 +76,19 @@ function buildEnv() {
|
|
|
75
76
|
function execEnv() {
|
|
76
77
|
return { ...buildEnv() };
|
|
77
78
|
}
|
|
79
|
+
function resolvePtyFile(bin, env = execEnv()) {
|
|
80
|
+
if (process.platform !== "win32" || path5.isAbsolute(bin)) return bin;
|
|
81
|
+
const pathKey = Object.keys(env).find((key) => key.toLowerCase() === "path");
|
|
82
|
+
const dirs = (pathKey ? env[pathKey] ?? "" : "").split(path5.delimiter).filter(Boolean);
|
|
83
|
+
const names = path5.extname(bin) ? [bin] : [`${bin}.exe`, `${bin}.com`];
|
|
84
|
+
for (const dir of dirs) {
|
|
85
|
+
for (const name of names) {
|
|
86
|
+
const candidate = path5.join(dir, name);
|
|
87
|
+
if (fs3.existsSync(candidate)) return candidate;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return bin;
|
|
91
|
+
}
|
|
78
92
|
var cached;
|
|
79
93
|
var init_env = __esm({
|
|
80
94
|
"packages/core/src/env.ts"() {
|
|
@@ -284,7 +298,7 @@ var init_session_backend = __esm({
|
|
|
284
298
|
|
|
285
299
|
// packages/core/src/tmux-backend.ts
|
|
286
300
|
import { execFile as execFile3, execFileSync as execFileSync2 } from "child_process";
|
|
287
|
-
import
|
|
301
|
+
import fs4 from "fs";
|
|
288
302
|
import path7 from "path";
|
|
289
303
|
import * as nodePty2 from "node-pty";
|
|
290
304
|
function q(value) {
|
|
@@ -357,8 +371,8 @@ var init_tmux_backend = __esm({
|
|
|
357
371
|
return path7.join(this.logDir, `${this.sessionName(key)}.status`);
|
|
358
372
|
}
|
|
359
373
|
ensureFiles() {
|
|
360
|
-
|
|
361
|
-
|
|
374
|
+
fs4.mkdirSync(this.logDir, { recursive: true });
|
|
375
|
+
fs4.writeFileSync(this.confPath, TMUX_CONF);
|
|
362
376
|
}
|
|
363
377
|
/**
|
|
364
378
|
* The pane's command: the login shell running `command` (or staying
|
|
@@ -388,7 +402,7 @@ var init_tmux_backend = __esm({
|
|
|
388
402
|
this.detach(key);
|
|
389
403
|
if (!reattach) {
|
|
390
404
|
if (alive) await this.tmux("kill-session", "-t", `=${name}`);
|
|
391
|
-
|
|
405
|
+
fs4.rmSync(this.statusPath(key), { force: true });
|
|
392
406
|
const created = await this.tmux(
|
|
393
407
|
"new-session",
|
|
394
408
|
"-d",
|
|
@@ -460,7 +474,7 @@ var init_tmux_backend = __esm({
|
|
|
460
474
|
}
|
|
461
475
|
readExitCode(key) {
|
|
462
476
|
try {
|
|
463
|
-
const code2 = Number(
|
|
477
|
+
const code2 = Number(fs4.readFileSync(this.statusPath(key), "utf8").trim());
|
|
464
478
|
return Number.isFinite(code2) ? code2 : null;
|
|
465
479
|
} catch {
|
|
466
480
|
return null;
|
|
@@ -680,10 +694,10 @@ var init_launch = __esm({
|
|
|
680
694
|
// packages/core/src/attachments.ts
|
|
681
695
|
import { randomUUID } from "crypto";
|
|
682
696
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
683
|
-
import
|
|
697
|
+
import fs7 from "fs";
|
|
684
698
|
import path10 from "path";
|
|
685
699
|
function fileToAttachmentInput(filePath) {
|
|
686
|
-
const bytes =
|
|
700
|
+
const bytes = fs7.readFileSync(filePath);
|
|
687
701
|
const extension = path10.extname(filePath).toLowerCase();
|
|
688
702
|
return {
|
|
689
703
|
name: path10.basename(filePath),
|
|
@@ -721,10 +735,10 @@ function ensureAttachmentExclude(worktreePath) {
|
|
|
721
735
|
{ cwd: worktreePath, encoding: "utf8", env: execEnv() }
|
|
722
736
|
).trim();
|
|
723
737
|
const entry = `${ATTACHMENTS_DIR}/`;
|
|
724
|
-
const content =
|
|
738
|
+
const content = fs7.existsSync(excludePath) ? fs7.readFileSync(excludePath, "utf8") : "";
|
|
725
739
|
if (!content.split(/\r?\n/).includes(entry)) {
|
|
726
|
-
|
|
727
|
-
|
|
740
|
+
fs7.mkdirSync(path10.dirname(excludePath), { recursive: true });
|
|
741
|
+
fs7.appendFileSync(excludePath, `
|
|
728
742
|
# VibeFlow task attachments (runtime-only)
|
|
729
743
|
${entry}
|
|
730
744
|
`);
|
|
@@ -744,11 +758,11 @@ function writeAttachmentsTo(attachmentDir, inputs) {
|
|
|
744
758
|
name: safeAttachmentName(input.name),
|
|
745
759
|
bytes: decodeAttachment(input)
|
|
746
760
|
}));
|
|
747
|
-
|
|
761
|
+
fs7.mkdirSync(attachmentDir, { recursive: true });
|
|
748
762
|
return decodedInputs.map(({ input, name, bytes }) => {
|
|
749
763
|
const id = randomUUID().slice(0, 8);
|
|
750
764
|
const filePath = path10.join(attachmentDir, `${id}-${name}`);
|
|
751
|
-
|
|
765
|
+
fs7.writeFileSync(filePath, bytes);
|
|
752
766
|
return { id, name, mime: input.mime, path: filePath };
|
|
753
767
|
});
|
|
754
768
|
}
|
|
@@ -1093,7 +1107,7 @@ var init_progress = __esm({
|
|
|
1093
1107
|
|
|
1094
1108
|
// packages/tui/src/task-form.ts
|
|
1095
1109
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
1096
|
-
import
|
|
1110
|
+
import fs26 from "fs";
|
|
1097
1111
|
import os8 from "os";
|
|
1098
1112
|
import path29 from "path";
|
|
1099
1113
|
import React, { useEffect, useRef, useState } from "react";
|
|
@@ -1221,17 +1235,17 @@ function editorCommand(env, platform) {
|
|
|
1221
1235
|
return env.VISUAL?.trim() || env.EDITOR?.trim() || (platform === "win32" ? "notepad" : "vi");
|
|
1222
1236
|
}
|
|
1223
1237
|
function editInEditor(text) {
|
|
1224
|
-
const dir =
|
|
1238
|
+
const dir = fs26.mkdtempSync(path29.join(os8.tmpdir(), "vibeflow-"));
|
|
1225
1239
|
const file = path29.join(dir, "description.md");
|
|
1226
1240
|
try {
|
|
1227
|
-
|
|
1241
|
+
fs26.writeFileSync(file, text);
|
|
1228
1242
|
const cmd = editorCommand(process.env, process.platform);
|
|
1229
1243
|
const r = spawnSync2(`${cmd} "${file}"`, { stdio: "inherit", shell: true });
|
|
1230
1244
|
if (r.error) return { error: `\u7121\u6CD5\u555F\u52D5\u7DE8\u8F2F\u5668\uFF08${cmd}\uFF09\uFF1A${r.error.message}` };
|
|
1231
1245
|
if (r.status !== 0) return { error: `\u7DE8\u8F2F\u5668\uFF08${cmd}\uFF09\u7D50\u675F\u78BC ${r.status}\uFF0C\u63CF\u8FF0\u672A\u8B8A\u66F4` };
|
|
1232
|
-
return { text:
|
|
1246
|
+
return { text: fs26.readFileSync(file, "utf8").replace(/\r?\n$/, "") };
|
|
1233
1247
|
} finally {
|
|
1234
|
-
|
|
1248
|
+
fs26.rmSync(dir, { recursive: true, force: true });
|
|
1235
1249
|
}
|
|
1236
1250
|
}
|
|
1237
1251
|
function cycle(list, current, step) {
|
|
@@ -1305,7 +1319,7 @@ function FormView({ api, ctx, initial, initialFocus, initialMessage, pristine, o
|
|
|
1305
1319
|
if (value2) setProject(path29.resolve(value2.replace(/^~(?=$|\/)/, os8.homedir())));
|
|
1306
1320
|
} else if (editing === "attachments" && value2) {
|
|
1307
1321
|
const file = path29.resolve(value2.replace(/^~(?=$|\/)/, os8.homedir()));
|
|
1308
|
-
if (!
|
|
1322
|
+
if (!fs26.existsSync(file) || !fs26.statSync(file).isFile()) {
|
|
1309
1323
|
setMessage(`\u627E\u4E0D\u5230\u6A94\u6848\uFF1A${file}`);
|
|
1310
1324
|
return;
|
|
1311
1325
|
}
|
|
@@ -1979,7 +1993,7 @@ var init_src = __esm({
|
|
|
1979
1993
|
});
|
|
1980
1994
|
|
|
1981
1995
|
// packages/cli/src/main.ts
|
|
1982
|
-
import
|
|
1996
|
+
import fs27 from "fs";
|
|
1983
1997
|
import path31 from "path";
|
|
1984
1998
|
import { fileURLToPath } from "url";
|
|
1985
1999
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
@@ -2651,7 +2665,7 @@ function createLocalTransport(core) {
|
|
|
2651
2665
|
init_tmux_backend();
|
|
2652
2666
|
|
|
2653
2667
|
// packages/core/src/pty-helper.ts
|
|
2654
|
-
import
|
|
2668
|
+
import fs5 from "fs";
|
|
2655
2669
|
import path8 from "path";
|
|
2656
2670
|
import { createRequire } from "module";
|
|
2657
2671
|
function nodePtyRoot() {
|
|
@@ -2671,17 +2685,17 @@ function ensurePtySpawnHelper(root = nodePtyRoot()) {
|
|
|
2671
2685
|
for (const file of candidates) {
|
|
2672
2686
|
let stat;
|
|
2673
2687
|
try {
|
|
2674
|
-
stat =
|
|
2688
|
+
stat = fs5.statSync(file);
|
|
2675
2689
|
} catch {
|
|
2676
2690
|
continue;
|
|
2677
2691
|
}
|
|
2678
2692
|
try {
|
|
2679
|
-
|
|
2693
|
+
fs5.accessSync(file, fs5.constants.X_OK);
|
|
2680
2694
|
continue;
|
|
2681
2695
|
} catch {
|
|
2682
2696
|
}
|
|
2683
2697
|
try {
|
|
2684
|
-
|
|
2698
|
+
fs5.chmodSync(file, stat.mode & 4095 | 73);
|
|
2685
2699
|
} catch (err) {
|
|
2686
2700
|
const uid = process.getuid?.();
|
|
2687
2701
|
failures.push({ path: file, error: err.message, ownedByOther: uid !== void 0 && stat.uid !== uid });
|
|
@@ -2700,7 +2714,7 @@ import { parseArgs } from "node:util";
|
|
|
2700
2714
|
// packages/core/src/tasks.ts
|
|
2701
2715
|
import path13 from "path";
|
|
2702
2716
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2703
|
-
import
|
|
2717
|
+
import fs10 from "fs/promises";
|
|
2704
2718
|
|
|
2705
2719
|
// packages/core/src/branch-name.ts
|
|
2706
2720
|
import os2 from "os";
|
|
@@ -2708,6 +2722,9 @@ import os2 from "os";
|
|
|
2708
2722
|
// packages/core/src/agent-print.ts
|
|
2709
2723
|
init_env();
|
|
2710
2724
|
import { spawn as spawn3 } from "child_process";
|
|
2725
|
+
function quoteWindowsBin(bin) {
|
|
2726
|
+
return /\s/.test(bin) && !bin.startsWith('"') ? `"${bin}"` : bin;
|
|
2727
|
+
}
|
|
2711
2728
|
function runAgentPrint(bin, args, input, opts) {
|
|
2712
2729
|
const maxBuffer = opts.maxBuffer ?? 1024 * 1024;
|
|
2713
2730
|
return new Promise((resolve, reject) => {
|
|
@@ -2717,7 +2734,7 @@ function runAgentPrint(bin, args, input, opts) {
|
|
|
2717
2734
|
timeout: opts.timeout,
|
|
2718
2735
|
windowsHide: true
|
|
2719
2736
|
};
|
|
2720
|
-
const proc = process.platform === "win32" ? spawn3([bin, ...args].join(" "), { ...spawnOpts, shell: true }) : spawn3(bin, args, spawnOpts);
|
|
2737
|
+
const proc = process.platform === "win32" ? spawn3([quoteWindowsBin(bin), ...args].join(" "), { ...spawnOpts, shell: true }) : spawn3(bin, args, spawnOpts);
|
|
2721
2738
|
let stdout = "";
|
|
2722
2739
|
let stderr = "";
|
|
2723
2740
|
let settled = false;
|
|
@@ -2808,15 +2825,15 @@ async function generateBranchName(title, description) {
|
|
|
2808
2825
|
import { execFile as execFile5 } from "child_process";
|
|
2809
2826
|
import { promisify as promisify2 } from "util";
|
|
2810
2827
|
import path12 from "path";
|
|
2811
|
-
import
|
|
2828
|
+
import fs9 from "fs/promises";
|
|
2812
2829
|
|
|
2813
2830
|
// packages/core/src/subagents.ts
|
|
2814
|
-
import
|
|
2831
|
+
import fs6 from "fs";
|
|
2815
2832
|
import path9 from "path";
|
|
2816
2833
|
var SUBAGENTS_DIR = ".vibeflow-subagents";
|
|
2817
2834
|
function resetSubAgents(cwd) {
|
|
2818
2835
|
try {
|
|
2819
|
-
|
|
2836
|
+
fs6.rmSync(path9.join(cwd, SUBAGENTS_DIR), { recursive: true, force: true });
|
|
2820
2837
|
} catch {
|
|
2821
2838
|
}
|
|
2822
2839
|
}
|
|
@@ -2916,7 +2933,7 @@ function readSubAgents(cwd) {
|
|
|
2916
2933
|
const dir = path9.join(cwd, SUBAGENTS_DIR);
|
|
2917
2934
|
let names;
|
|
2918
2935
|
try {
|
|
2919
|
-
names =
|
|
2936
|
+
names = fs6.readdirSync(dir).filter((n) => n.endsWith(".json"));
|
|
2920
2937
|
} catch {
|
|
2921
2938
|
return [];
|
|
2922
2939
|
}
|
|
@@ -2924,7 +2941,7 @@ function readSubAgents(cwd) {
|
|
|
2924
2941
|
for (const name of names) {
|
|
2925
2942
|
let raw;
|
|
2926
2943
|
try {
|
|
2927
|
-
raw =
|
|
2944
|
+
raw = fs6.readFileSync(path9.join(dir, name), "utf8");
|
|
2928
2945
|
} catch {
|
|
2929
2946
|
continue;
|
|
2930
2947
|
}
|
|
@@ -2951,13 +2968,13 @@ function watchSubAgents(sessionKey, cwd, onUpdate) {
|
|
|
2951
2968
|
};
|
|
2952
2969
|
const entry = { dir, lastJson: null, sync };
|
|
2953
2970
|
watchers.set(sessionKey, entry);
|
|
2954
|
-
|
|
2971
|
+
fs6.watchFile(dir, { interval: 800 }, sync);
|
|
2955
2972
|
sync();
|
|
2956
2973
|
}
|
|
2957
2974
|
function unwatchSubAgents(sessionKey) {
|
|
2958
2975
|
const entry = watchers.get(sessionKey);
|
|
2959
2976
|
if (entry) {
|
|
2960
|
-
|
|
2977
|
+
fs6.unwatchFile(entry.dir);
|
|
2961
2978
|
watchers.delete(sessionKey);
|
|
2962
2979
|
}
|
|
2963
2980
|
}
|
|
@@ -3300,7 +3317,7 @@ function createGithubService(options) {
|
|
|
3300
3317
|
init_attachments();
|
|
3301
3318
|
|
|
3302
3319
|
// packages/core/src/artifacts.ts
|
|
3303
|
-
import
|
|
3320
|
+
import fs8 from "fs";
|
|
3304
3321
|
import path11 from "path";
|
|
3305
3322
|
var ARTIFACTS_DIR_SUFFIX2 = ".artifacts";
|
|
3306
3323
|
var SCRATCH_DIR_NAME2 = "scratch";
|
|
@@ -3332,12 +3349,12 @@ function agentArtifactsPath(baseDir, worktreePath) {
|
|
|
3332
3349
|
function ensureTaskArtifactDirs(task) {
|
|
3333
3350
|
if (!task.worktreePath) throw new Error("\u4EFB\u52D9\u5C1A\u672A\u5EFA\u7ACB worktree");
|
|
3334
3351
|
const dir = task.workspacePath ? agentArtifactsPath(task.workspacePath, task.worktreePath) : path11.join(task.worktreePath, ARTIFACTS_FALLBACK_DIR2);
|
|
3335
|
-
|
|
3352
|
+
fs8.mkdirSync(path11.join(dir, SCRATCH_DIR_NAME2), { recursive: true });
|
|
3336
3353
|
return dir;
|
|
3337
3354
|
}
|
|
3338
3355
|
function addTaskArtifact(task, filePath) {
|
|
3339
3356
|
const source = path11.resolve(filePath);
|
|
3340
|
-
const stat =
|
|
3357
|
+
const stat = fs8.lstatSync(source);
|
|
3341
3358
|
if (!stat.isFile()) throw new Error("Artifact \u4F86\u6E90\u5FC5\u9808\u662F\u4E00\u822C\u6A94\u6848");
|
|
3342
3359
|
const dir = ensureTaskArtifactDirs(task);
|
|
3343
3360
|
if (path11.dirname(source) === dir) return source;
|
|
@@ -3345,7 +3362,7 @@ function addTaskArtifact(task, filePath) {
|
|
|
3345
3362
|
for (let index = 0; index < 1e3; index += 1) {
|
|
3346
3363
|
const destination = path11.join(dir, index === 0 ? `${name}${ext}` : `${name}-${index}${ext}`);
|
|
3347
3364
|
try {
|
|
3348
|
-
|
|
3365
|
+
fs8.copyFileSync(source, destination, fs8.constants.COPYFILE_EXCL);
|
|
3349
3366
|
return destination;
|
|
3350
3367
|
} catch (error) {
|
|
3351
3368
|
if (error.code !== "EEXIST") throw error;
|
|
@@ -3366,16 +3383,16 @@ function mediaKind(filePath, size) {
|
|
|
3366
3383
|
function sniffKind(filePath) {
|
|
3367
3384
|
let fd;
|
|
3368
3385
|
try {
|
|
3369
|
-
fd =
|
|
3386
|
+
fd = fs8.openSync(filePath, "r");
|
|
3370
3387
|
const buf = Buffer.alloc(SNIFF_BYTES);
|
|
3371
|
-
const read =
|
|
3388
|
+
const read = fs8.readSync(fd, buf, 0, SNIFF_BYTES, 0);
|
|
3372
3389
|
return buf.subarray(0, read).includes(0) ? "binary" : "text";
|
|
3373
3390
|
} catch {
|
|
3374
3391
|
return "binary";
|
|
3375
3392
|
} finally {
|
|
3376
3393
|
if (fd !== void 0) {
|
|
3377
3394
|
try {
|
|
3378
|
-
|
|
3395
|
+
fs8.closeSync(fd);
|
|
3379
3396
|
} catch {
|
|
3380
3397
|
}
|
|
3381
3398
|
}
|
|
@@ -3385,8 +3402,8 @@ function resolveInside(dir, name) {
|
|
|
3385
3402
|
let root;
|
|
3386
3403
|
let target;
|
|
3387
3404
|
try {
|
|
3388
|
-
root =
|
|
3389
|
-
target =
|
|
3405
|
+
root = fs8.realpathSync(path11.resolve(dir));
|
|
3406
|
+
target = fs8.realpathSync(path11.resolve(root, name));
|
|
3390
3407
|
} catch {
|
|
3391
3408
|
return null;
|
|
3392
3409
|
}
|
|
@@ -3399,7 +3416,7 @@ function listArtifacts(dir) {
|
|
|
3399
3416
|
if (found2.length >= MAX_ARTIFACTS) return;
|
|
3400
3417
|
let dirents;
|
|
3401
3418
|
try {
|
|
3402
|
-
dirents =
|
|
3419
|
+
dirents = fs8.readdirSync(current, { withFileTypes: true });
|
|
3403
3420
|
} catch {
|
|
3404
3421
|
return;
|
|
3405
3422
|
}
|
|
@@ -3415,7 +3432,7 @@ function listArtifacts(dir) {
|
|
|
3415
3432
|
if (!dirent.isFile()) continue;
|
|
3416
3433
|
let stat;
|
|
3417
3434
|
try {
|
|
3418
|
-
stat =
|
|
3435
|
+
stat = fs8.statSync(full);
|
|
3419
3436
|
} catch {
|
|
3420
3437
|
continue;
|
|
3421
3438
|
}
|
|
@@ -3442,7 +3459,7 @@ function readArtifact(dir, name) {
|
|
|
3442
3459
|
if (!target) return null;
|
|
3443
3460
|
let stat;
|
|
3444
3461
|
try {
|
|
3445
|
-
stat =
|
|
3462
|
+
stat = fs8.lstatSync(target);
|
|
3446
3463
|
if (!stat.isFile()) return null;
|
|
3447
3464
|
} catch {
|
|
3448
3465
|
return null;
|
|
@@ -3452,12 +3469,12 @@ function readArtifact(dir, name) {
|
|
|
3452
3469
|
if (media?.mime) {
|
|
3453
3470
|
return {
|
|
3454
3471
|
kind: media.kind,
|
|
3455
|
-
dataUrl: `data:${media.mime};base64,${
|
|
3472
|
+
dataUrl: `data:${media.mime};base64,${fs8.readFileSync(target).toString("base64")}`
|
|
3456
3473
|
};
|
|
3457
3474
|
}
|
|
3458
3475
|
if (media?.kind === "binary") return { kind: "binary" };
|
|
3459
3476
|
if (sniffKind(target) === "binary") return { kind: "binary" };
|
|
3460
|
-
const buf =
|
|
3477
|
+
const buf = fs8.readFileSync(target);
|
|
3461
3478
|
return {
|
|
3462
3479
|
kind: "text",
|
|
3463
3480
|
text: buf.subarray(0, MAX_TEXT_BYTES).toString("utf8"),
|
|
@@ -3469,7 +3486,7 @@ function readArtifact(dir, name) {
|
|
|
3469
3486
|
}
|
|
3470
3487
|
function deleteArtifacts(baseDir, worktreePath) {
|
|
3471
3488
|
try {
|
|
3472
|
-
|
|
3489
|
+
fs8.rmSync(agentArtifactsPath(baseDir, worktreePath), {
|
|
3473
3490
|
recursive: true,
|
|
3474
3491
|
force: true
|
|
3475
3492
|
});
|
|
@@ -3538,7 +3555,7 @@ async function getGitInfo(projectPath) {
|
|
|
3538
3555
|
async function appendLineIfMissing(filePath, entry, header, options = {}) {
|
|
3539
3556
|
let content = "";
|
|
3540
3557
|
try {
|
|
3541
|
-
content = await
|
|
3558
|
+
content = await fs9.readFile(filePath, "utf8");
|
|
3542
3559
|
} catch {
|
|
3543
3560
|
content = "";
|
|
3544
3561
|
}
|
|
@@ -3551,12 +3568,12 @@ ${header}
|
|
|
3551
3568
|
${entry}
|
|
3552
3569
|
`;
|
|
3553
3570
|
if (options.mkdir) {
|
|
3554
|
-
await
|
|
3571
|
+
await fs9.mkdir(path12.dirname(filePath), { recursive: true });
|
|
3555
3572
|
}
|
|
3556
|
-
await
|
|
3573
|
+
await fs9.writeFile(filePath, content + addition, "utf8");
|
|
3557
3574
|
}
|
|
3558
3575
|
async function initRepository(projectPath) {
|
|
3559
|
-
await
|
|
3576
|
+
await fs9.mkdir(projectPath, { recursive: true });
|
|
3560
3577
|
let alreadyRepo = false;
|
|
3561
3578
|
try {
|
|
3562
3579
|
await git(projectPath, ["rev-parse", "--is-inside-work-tree"]);
|
|
@@ -3673,7 +3690,7 @@ async function assertBranchAvailable(projectPath, workspacePath, branch) {
|
|
|
3673
3690
|
{ code: "BRANCH_ALREADY_EXISTS" }
|
|
3674
3691
|
);
|
|
3675
3692
|
}
|
|
3676
|
-
const dirTaken = await
|
|
3693
|
+
const dirTaken = await fs9.access(path12.join(workspacePath, worktreeDirName(branch))).then(() => true).catch(() => false);
|
|
3677
3694
|
if (dirTaken) {
|
|
3678
3695
|
throw Object.assign(
|
|
3679
3696
|
new Error(`\u5DE5\u4F5C\u5340\u8CC7\u6599\u593E\u5DF2\u5B58\u5728\uFF1A${worktreeDirName(branch)}`),
|
|
@@ -3689,7 +3706,7 @@ async function resolveBranchName(projectPath, workspacePath, taskId, preferredBr
|
|
|
3689
3706
|
} catch {
|
|
3690
3707
|
return fallback;
|
|
3691
3708
|
}
|
|
3692
|
-
const dirTaken = await
|
|
3709
|
+
const dirTaken = await fs9.access(path12.join(workspacePath, worktreeDirName(preferredBranch))).then(() => true).catch(() => false);
|
|
3693
3710
|
if (dirTaken || await branchExists(projectPath, preferredBranch)) {
|
|
3694
3711
|
return `${preferredBranch}-${taskId}`;
|
|
3695
3712
|
}
|
|
@@ -3736,10 +3753,10 @@ async function ignoredEntryFitsCopyBudget(src) {
|
|
|
3736
3753
|
const stack = [src];
|
|
3737
3754
|
while (stack.length > 0) {
|
|
3738
3755
|
const current = stack.pop();
|
|
3739
|
-
const stat = await
|
|
3756
|
+
const stat = await fs9.lstat(current);
|
|
3740
3757
|
if (stat.isSymbolicLink()) continue;
|
|
3741
3758
|
if (stat.isDirectory()) {
|
|
3742
|
-
const children2 = await
|
|
3759
|
+
const children2 = await fs9.readdir(current, { withFileTypes: true });
|
|
3743
3760
|
files += children2.length;
|
|
3744
3761
|
if (files > MAX_IGNORED_COPY_FILES) return false;
|
|
3745
3762
|
for (const child of children2) stack.push(path12.join(current, child.name));
|
|
@@ -3784,41 +3801,41 @@ function dropCoveredEntries(entries) {
|
|
|
3784
3801
|
async function copyIgnoredEntry(projectPath, worktreePath, entry) {
|
|
3785
3802
|
const src = path12.join(projectPath, entry);
|
|
3786
3803
|
const dest = path12.join(worktreePath, entry);
|
|
3787
|
-
await
|
|
3788
|
-
await
|
|
3804
|
+
await fs9.mkdir(path12.dirname(dest), { recursive: true });
|
|
3805
|
+
await fs9.cp(src, dest, {
|
|
3789
3806
|
recursive: true,
|
|
3790
3807
|
filter: async (from, to) => {
|
|
3791
|
-
if (!(await
|
|
3808
|
+
if (!(await fs9.lstat(from)).isSymbolicLink()) return true;
|
|
3792
3809
|
await copyIgnoredLink(projectPath, worktreePath, from, to);
|
|
3793
3810
|
return false;
|
|
3794
3811
|
}
|
|
3795
3812
|
});
|
|
3796
3813
|
}
|
|
3797
3814
|
async function copyIgnoredLink(projectPath, worktreePath, from, to) {
|
|
3798
|
-
const raw = (await
|
|
3815
|
+
const raw = (await fs9.readlink(from)).replace(/^\\\\\?\\/, "");
|
|
3799
3816
|
const resolved = path12.resolve(path12.dirname(from), raw);
|
|
3800
3817
|
const inProject = path12.relative(projectPath, resolved);
|
|
3801
3818
|
const insideProject = inProject !== "" && !inProject.startsWith("..") && !path12.isAbsolute(inProject);
|
|
3802
3819
|
const target = insideProject ? path12.join(worktreePath, inProject) : resolved;
|
|
3803
3820
|
let isDirectory;
|
|
3804
3821
|
try {
|
|
3805
|
-
isDirectory = (await
|
|
3822
|
+
isDirectory = (await fs9.stat(resolved)).isDirectory();
|
|
3806
3823
|
} catch {
|
|
3807
3824
|
return;
|
|
3808
3825
|
}
|
|
3809
|
-
await
|
|
3826
|
+
await fs9.mkdir(path12.dirname(to), { recursive: true });
|
|
3810
3827
|
if (process.platform !== "win32") {
|
|
3811
|
-
await
|
|
3828
|
+
await fs9.symlink(path12.isAbsolute(raw) ? target : raw, to);
|
|
3812
3829
|
return;
|
|
3813
3830
|
}
|
|
3814
3831
|
if (isDirectory) {
|
|
3815
|
-
await
|
|
3832
|
+
await fs9.symlink(target, to, "junction");
|
|
3816
3833
|
return;
|
|
3817
3834
|
}
|
|
3818
3835
|
try {
|
|
3819
|
-
await
|
|
3836
|
+
await fs9.symlink(target, to, "file");
|
|
3820
3837
|
} catch {
|
|
3821
|
-
await
|
|
3838
|
+
await fs9.copyFile(resolved, to);
|
|
3822
3839
|
}
|
|
3823
3840
|
}
|
|
3824
3841
|
async function copySmallIgnoredFiles(projectPath, worktreePath) {
|
|
@@ -3966,7 +3983,7 @@ async function resetWorktreeToBase(worktreePath, baseBranch) {
|
|
|
3966
3983
|
const baseRef = await resolveBaseRef(worktreePath, baseBranch);
|
|
3967
3984
|
await git(worktreePath, ["reset", "--hard", baseRef]);
|
|
3968
3985
|
await git(worktreePath, ["clean", "-fd"]);
|
|
3969
|
-
await
|
|
3986
|
+
await fs9.rm(path12.join(worktreePath, ARTIFACTS_FALLBACK_DIR2), {
|
|
3970
3987
|
recursive: true,
|
|
3971
3988
|
force: true
|
|
3972
3989
|
});
|
|
@@ -4057,7 +4074,7 @@ async function collectDiffEntries(worktreePath, baseRef) {
|
|
|
4057
4074
|
await Promise.all(
|
|
4058
4075
|
entries.map(async (entry) => {
|
|
4059
4076
|
try {
|
|
4060
|
-
const stat = await
|
|
4077
|
+
const stat = await fs9.stat(path12.join(worktreePath, entry.path));
|
|
4061
4078
|
entry.revision = `${stat.mtimeMs}:${stat.size}`;
|
|
4062
4079
|
} catch {
|
|
4063
4080
|
entry.revision = `${entry.status}:${entry.additions}:${entry.deletions}`;
|
|
@@ -4077,7 +4094,7 @@ async function readDiffFile(worktreePath, baseRef, entry) {
|
|
|
4077
4094
|
let newValue = "";
|
|
4078
4095
|
if (entry.status !== "D") {
|
|
4079
4096
|
try {
|
|
4080
|
-
newValue = await
|
|
4097
|
+
newValue = await fs9.readFile(path12.join(worktreePath, entry.path), "utf8");
|
|
4081
4098
|
} catch {
|
|
4082
4099
|
newValue = await git(worktreePath, ["show", `HEAD:${entry.path}`]).catch(() => "");
|
|
4083
4100
|
}
|
|
@@ -4336,7 +4353,7 @@ init_attachments();
|
|
|
4336
4353
|
async function createTaskFromInput(input) {
|
|
4337
4354
|
const { projectPath } = input;
|
|
4338
4355
|
try {
|
|
4339
|
-
await
|
|
4356
|
+
await fs10.access(projectPath);
|
|
4340
4357
|
} catch {
|
|
4341
4358
|
throw Object.assign(new Error(`\u627E\u4E0D\u5230\u5C08\u6848\u8DEF\u5F91\uFF1A${projectPath}`), { code: "PROJECT_NOT_FOUND" });
|
|
4342
4359
|
}
|
|
@@ -4355,7 +4372,7 @@ async function createTaskFromInput(input) {
|
|
|
4355
4372
|
resolveWorkstationPath(store.get("settings")),
|
|
4356
4373
|
projectName
|
|
4357
4374
|
);
|
|
4358
|
-
await
|
|
4375
|
+
await fs10.mkdir(workspacePath, { recursive: true });
|
|
4359
4376
|
if (explicitBranch) {
|
|
4360
4377
|
await assertBranchAvailable(projectPath, workspacePath, explicitBranch);
|
|
4361
4378
|
}
|
|
@@ -4412,7 +4429,7 @@ async function provisionTaskWorktree(task) {
|
|
|
4412
4429
|
code: "WORKTREE_CREATE_FAILED"
|
|
4413
4430
|
});
|
|
4414
4431
|
}
|
|
4415
|
-
await
|
|
4432
|
+
await fs10.mkdir(task.workspacePath, { recursive: true });
|
|
4416
4433
|
if (task.branchExplicit) {
|
|
4417
4434
|
await assertBranchAvailable(task.projectPath, task.workspacePath, task.branch);
|
|
4418
4435
|
}
|
|
@@ -4697,7 +4714,7 @@ async function taskCommand(argv) {
|
|
|
4697
4714
|
}
|
|
4698
4715
|
|
|
4699
4716
|
// packages/cli/src/host.ts
|
|
4700
|
-
import
|
|
4717
|
+
import fs24 from "fs";
|
|
4701
4718
|
import path27 from "path";
|
|
4702
4719
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
4703
4720
|
|
|
@@ -4725,12 +4742,12 @@ var EventBus = class {
|
|
|
4725
4742
|
};
|
|
4726
4743
|
|
|
4727
4744
|
// packages/core/src/library-builtins.ts
|
|
4728
|
-
import
|
|
4745
|
+
import fs12 from "fs";
|
|
4729
4746
|
import path15 from "path";
|
|
4730
4747
|
|
|
4731
4748
|
// packages/core/src/library.ts
|
|
4732
4749
|
import { createHash } from "crypto";
|
|
4733
|
-
import
|
|
4750
|
+
import fs11 from "fs";
|
|
4734
4751
|
import path14 from "path";
|
|
4735
4752
|
var LIBRARY_DIR = "library";
|
|
4736
4753
|
var LIBRARY_KINDS = ["skill", "prompt", "script"];
|
|
@@ -4778,7 +4795,7 @@ function indexPath(root) {
|
|
|
4778
4795
|
function readIndexFile(root) {
|
|
4779
4796
|
let raw;
|
|
4780
4797
|
try {
|
|
4781
|
-
raw =
|
|
4798
|
+
raw = fs11.readFileSync(indexPath(root), "utf8");
|
|
4782
4799
|
} catch {
|
|
4783
4800
|
return { version: 1, entries: {} };
|
|
4784
4801
|
}
|
|
@@ -4799,25 +4816,25 @@ function indexIsCorrupt(root) {
|
|
|
4799
4816
|
return readIndexFile(root) === null;
|
|
4800
4817
|
}
|
|
4801
4818
|
function writeIndex(root, index) {
|
|
4802
|
-
|
|
4819
|
+
fs11.mkdirSync(root, { recursive: true });
|
|
4803
4820
|
const file = indexPath(root);
|
|
4804
|
-
if (indexIsCorrupt(root))
|
|
4821
|
+
if (indexIsCorrupt(root)) fs11.renameSync(file, `${file}.corrupt-${Date.now()}`);
|
|
4805
4822
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
4806
|
-
|
|
4823
|
+
fs11.writeFileSync(tmp, `${JSON.stringify(index, null, 2)}
|
|
4807
4824
|
`);
|
|
4808
|
-
|
|
4825
|
+
fs11.renameSync(tmp, file);
|
|
4809
4826
|
}
|
|
4810
4827
|
function ensureLibrary(root) {
|
|
4811
4828
|
const paths = libraryPaths(root);
|
|
4812
4829
|
for (const kind of LIBRARY_KINDS) {
|
|
4813
|
-
|
|
4830
|
+
fs11.mkdirSync(path14.join(root, KIND_DIR[kind]), { recursive: true });
|
|
4814
4831
|
}
|
|
4815
4832
|
return paths;
|
|
4816
4833
|
}
|
|
4817
4834
|
function readSkillDescription(skillMdPath) {
|
|
4818
4835
|
let content;
|
|
4819
4836
|
try {
|
|
4820
|
-
content =
|
|
4837
|
+
content = fs11.readFileSync(skillMdPath, "utf8");
|
|
4821
4838
|
} catch {
|
|
4822
4839
|
return void 0;
|
|
4823
4840
|
}
|
|
@@ -4838,17 +4855,17 @@ var HASH_IGNORED = /* @__PURE__ */ new Set(["__pycache__", ".DS_Store"]);
|
|
|
4838
4855
|
function hashSkillDir(dir) {
|
|
4839
4856
|
const files = [];
|
|
4840
4857
|
const walk = (rel) => {
|
|
4841
|
-
for (const dirent of
|
|
4858
|
+
for (const dirent of fs11.readdirSync(path14.join(dir, rel), { withFileTypes: true })) {
|
|
4842
4859
|
if (HASH_IGNORED.has(dirent.name)) continue;
|
|
4843
4860
|
const child = rel ? `${rel}/${dirent.name}` : dirent.name;
|
|
4844
|
-
if (
|
|
4861
|
+
if (fs11.statSync(path14.join(dir, child)).isDirectory()) walk(child);
|
|
4845
4862
|
else files.push(child);
|
|
4846
4863
|
}
|
|
4847
4864
|
};
|
|
4848
4865
|
walk("");
|
|
4849
4866
|
const hash = createHash("sha256");
|
|
4850
4867
|
for (const rel of files.sort()) {
|
|
4851
|
-
hash.update(rel).update("\0").update(
|
|
4868
|
+
hash.update(rel).update("\0").update(fs11.readFileSync(path14.join(dir, rel))).update("\0");
|
|
4852
4869
|
}
|
|
4853
4870
|
return hash.digest("hex");
|
|
4854
4871
|
}
|
|
@@ -4858,7 +4875,7 @@ function builtinStatus(full, name, recorded, builtinDir) {
|
|
|
4858
4875
|
let updateAvailable = false;
|
|
4859
4876
|
if (modified && builtinDir) {
|
|
4860
4877
|
const shipped = path14.join(builtinDir, name);
|
|
4861
|
-
if (
|
|
4878
|
+
if (fs11.existsSync(path14.join(shipped, "SKILL.md"))) {
|
|
4862
4879
|
updateAvailable = hashSkillDir(shipped) !== recorded;
|
|
4863
4880
|
}
|
|
4864
4881
|
}
|
|
@@ -4874,7 +4891,7 @@ function listLibrary(root, builtinDir) {
|
|
|
4874
4891
|
const dir = path14.join(root, KIND_DIR[kind]);
|
|
4875
4892
|
let dirents;
|
|
4876
4893
|
try {
|
|
4877
|
-
dirents =
|
|
4894
|
+
dirents = fs11.readdirSync(dir, { withFileTypes: true });
|
|
4878
4895
|
} catch {
|
|
4879
4896
|
continue;
|
|
4880
4897
|
}
|
|
@@ -4883,14 +4900,14 @@ function listLibrary(root, builtinDir) {
|
|
|
4883
4900
|
const wantsDirectory = kind === "skill";
|
|
4884
4901
|
let stat;
|
|
4885
4902
|
try {
|
|
4886
|
-
stat =
|
|
4903
|
+
stat = fs11.statSync(path14.join(dir, dirent.name));
|
|
4887
4904
|
} catch {
|
|
4888
4905
|
continue;
|
|
4889
4906
|
}
|
|
4890
4907
|
if (stat.isDirectory() !== wantsDirectory) continue;
|
|
4891
4908
|
const name = dirent.name;
|
|
4892
4909
|
const full = path14.join(dir, name);
|
|
4893
|
-
if (wantsDirectory && !
|
|
4910
|
+
if (wantsDirectory && !fs11.existsSync(path14.join(full, "SKILL.md"))) continue;
|
|
4894
4911
|
const key = entryKey(kind, name);
|
|
4895
4912
|
const record2 = index.entries[key] ?? {};
|
|
4896
4913
|
entries.push({
|
|
@@ -4916,10 +4933,10 @@ function annotate(root, key, patch) {
|
|
|
4916
4933
|
function importEntry(root, kind, sourcePath) {
|
|
4917
4934
|
ensureLibrary(root);
|
|
4918
4935
|
const resolved = path14.resolve(sourcePath);
|
|
4919
|
-
const stat =
|
|
4936
|
+
const stat = fs11.statSync(resolved);
|
|
4920
4937
|
if (kind === "skill") {
|
|
4921
4938
|
if (!stat.isDirectory()) throw new Error("skill \u5FC5\u9808\u662F\u542B SKILL.md \u7684\u76EE\u9304");
|
|
4922
|
-
if (!
|
|
4939
|
+
if (!fs11.existsSync(path14.join(resolved, "SKILL.md"))) {
|
|
4923
4940
|
throw new Error("\u76EE\u9304\u5167\u627E\u4E0D\u5230 SKILL.md");
|
|
4924
4941
|
}
|
|
4925
4942
|
} else if (!stat.isFile()) {
|
|
@@ -4927,9 +4944,9 @@ function importEntry(root, kind, sourcePath) {
|
|
|
4927
4944
|
}
|
|
4928
4945
|
const name = safeLibraryName(path14.basename(resolved));
|
|
4929
4946
|
const target = entryPath(root, kind, name);
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
if (kind === "script")
|
|
4947
|
+
fs11.rmSync(target, { recursive: true, force: true });
|
|
4948
|
+
fs11.cpSync(resolved, target, { recursive: kind === "skill", dereference: true });
|
|
4949
|
+
if (kind === "script") fs11.chmodSync(target, 493);
|
|
4933
4950
|
const key = entryKey(kind, name);
|
|
4934
4951
|
const index = readIndex(root);
|
|
4935
4952
|
const { builtinHash: _hash, builtinDeleted: _deleted, ...kept } = index.entries[key] ?? {};
|
|
@@ -4941,13 +4958,13 @@ function createEntry(root, kind, rawName, content, description) {
|
|
|
4941
4958
|
ensureLibrary(root);
|
|
4942
4959
|
const name = safeLibraryName(rawName);
|
|
4943
4960
|
const target = entryPath(root, kind, name);
|
|
4944
|
-
if (
|
|
4961
|
+
if (fs11.existsSync(target)) throw new Error(`\u5DF2\u5B58\u5728\u540C\u540D\u9805\u76EE\uFF1A${name}`);
|
|
4945
4962
|
if (kind === "skill") {
|
|
4946
|
-
|
|
4947
|
-
|
|
4963
|
+
fs11.mkdirSync(target, { recursive: true });
|
|
4964
|
+
fs11.writeFileSync(path14.join(target, "SKILL.md"), content);
|
|
4948
4965
|
} else {
|
|
4949
|
-
|
|
4950
|
-
if (kind === "script")
|
|
4966
|
+
fs11.writeFileSync(target, content);
|
|
4967
|
+
if (kind === "script") fs11.chmodSync(target, 493);
|
|
4951
4968
|
}
|
|
4952
4969
|
annotate(root, entryKey(kind, name), {
|
|
4953
4970
|
importedAt: Date.now(),
|
|
@@ -4961,13 +4978,13 @@ function setEntryDescription(root, kind, name, description) {
|
|
|
4961
4978
|
}
|
|
4962
4979
|
function updateEntry(root, kind, name, content) {
|
|
4963
4980
|
const target = entryPath(root, kind, name);
|
|
4964
|
-
if (!
|
|
4965
|
-
|
|
4981
|
+
if (!fs11.existsSync(target)) throw new Error(`\u627E\u4E0D\u5230\u9805\u76EE\uFF1A${name}`);
|
|
4982
|
+
fs11.writeFileSync(kind === "skill" ? path14.join(target, "SKILL.md") : target, content);
|
|
4966
4983
|
return requireEntry(root, kind, name);
|
|
4967
4984
|
}
|
|
4968
4985
|
function readEntryContent(root, kind, name) {
|
|
4969
4986
|
const target = entryPath(root, kind, name);
|
|
4970
|
-
return
|
|
4987
|
+
return fs11.readFileSync(kind === "skill" ? path14.join(target, "SKILL.md") : target, "utf8");
|
|
4971
4988
|
}
|
|
4972
4989
|
function markBuiltinDeleted(root, key) {
|
|
4973
4990
|
const index = readIndex(root);
|
|
@@ -4975,7 +4992,7 @@ function markBuiltinDeleted(root, key) {
|
|
|
4975
4992
|
writeIndex(root, index);
|
|
4976
4993
|
}
|
|
4977
4994
|
function deleteEntry(root, kind, name) {
|
|
4978
|
-
|
|
4995
|
+
fs11.rmSync(entryPath(root, kind, name), { recursive: true, force: true });
|
|
4979
4996
|
const key = entryKey(kind, name);
|
|
4980
4997
|
const record2 = readIndex(root).entries[key];
|
|
4981
4998
|
if (record2?.builtinHash || record2?.builtinDeleted) {
|
|
@@ -4996,7 +5013,7 @@ function requireEntry(root, kind, name) {
|
|
|
4996
5013
|
}
|
|
4997
5014
|
function skillNamesIn(dir) {
|
|
4998
5015
|
try {
|
|
4999
|
-
return
|
|
5016
|
+
return fs11.readdirSync(dir, { withFileTypes: true }).filter((d) => !d.name.startsWith(".")).map((d) => d.name).filter((name) => fs11.existsSync(path14.join(dir, name, "SKILL.md"))).sort();
|
|
5000
5017
|
} catch {
|
|
5001
5018
|
return [];
|
|
5002
5019
|
}
|
|
@@ -5009,17 +5026,17 @@ function builtinSkillsDir() {
|
|
|
5009
5026
|
function installBuiltin(root, builtinDir, name) {
|
|
5010
5027
|
const target = entryPath(root, "skill", name);
|
|
5011
5028
|
const staging = entryPath(root, "skill", `.${name}.installing`);
|
|
5012
|
-
|
|
5029
|
+
fs12.rmSync(staging, { recursive: true, force: true });
|
|
5013
5030
|
try {
|
|
5014
|
-
|
|
5031
|
+
fs12.cpSync(path15.join(builtinDir, name), staging, {
|
|
5015
5032
|
recursive: true,
|
|
5016
5033
|
dereference: true,
|
|
5017
5034
|
filter: (src) => path15.basename(src) !== "__pycache__"
|
|
5018
5035
|
});
|
|
5019
|
-
|
|
5020
|
-
|
|
5036
|
+
fs12.rmSync(target, { recursive: true, force: true });
|
|
5037
|
+
fs12.renameSync(staging, target);
|
|
5021
5038
|
} finally {
|
|
5022
|
-
|
|
5039
|
+
fs12.rmSync(staging, { recursive: true, force: true });
|
|
5023
5040
|
}
|
|
5024
5041
|
return hashSkillDir(target);
|
|
5025
5042
|
}
|
|
@@ -5048,7 +5065,7 @@ function syncOne(root, builtinDir, name, result) {
|
|
|
5048
5065
|
if (record2.builtinDeleted) return;
|
|
5049
5066
|
const target = entryPath(root, "skill", name);
|
|
5050
5067
|
if (!record2.builtinHash) {
|
|
5051
|
-
if (
|
|
5068
|
+
if (fs12.existsSync(target)) return;
|
|
5052
5069
|
annotate(root, key, {
|
|
5053
5070
|
builtinHash: installBuiltin(root, builtinDir, name),
|
|
5054
5071
|
enabled: true,
|
|
@@ -5057,7 +5074,7 @@ function syncOne(root, builtinDir, name, result) {
|
|
|
5057
5074
|
result.installed.push(name);
|
|
5058
5075
|
return;
|
|
5059
5076
|
}
|
|
5060
|
-
if (!
|
|
5077
|
+
if (!fs12.existsSync(path15.join(target, "SKILL.md"))) {
|
|
5061
5078
|
markBuiltinDeleted(root, key);
|
|
5062
5079
|
return;
|
|
5063
5080
|
}
|
|
@@ -5071,7 +5088,7 @@ function restoreBuiltinSkill(root, builtinDir, name) {
|
|
|
5071
5088
|
throw new Error(`\u4E0D\u662F\u5167\u5EFA skill\uFF1A${name}`);
|
|
5072
5089
|
}
|
|
5073
5090
|
const key = entryKey("skill", name);
|
|
5074
|
-
if (
|
|
5091
|
+
if (fs12.existsSync(entryPath(root, "skill", name)) && !readIndex(root).entries[key]?.builtinHash) {
|
|
5075
5092
|
throw new Error(`\u5DF2\u6709\u540C\u540D\u7684\u81EA\u8A02\u9805\u76EE\uFF1A${name}`);
|
|
5076
5093
|
}
|
|
5077
5094
|
ensureLibrary(root);
|
|
@@ -5090,7 +5107,7 @@ function removedBuiltinSkills(root, builtinDir) {
|
|
|
5090
5107
|
if (!builtinDir) return [];
|
|
5091
5108
|
const index = readIndex(root);
|
|
5092
5109
|
return skillNamesIn(builtinDir).filter(
|
|
5093
|
-
(name) => index.entries[entryKey("skill", name)]?.builtinDeleted === true && !
|
|
5110
|
+
(name) => index.entries[entryKey("skill", name)]?.builtinDeleted === true && !fs12.existsSync(entryPath(root, "skill", name))
|
|
5094
5111
|
);
|
|
5095
5112
|
}
|
|
5096
5113
|
async function syncBuiltinsAtStartup() {
|
|
@@ -5105,28 +5122,28 @@ async function syncBuiltinsAtStartup() {
|
|
|
5105
5122
|
}
|
|
5106
5123
|
|
|
5107
5124
|
// packages/core/src/service.ts
|
|
5108
|
-
import
|
|
5125
|
+
import fs20 from "fs";
|
|
5109
5126
|
import os7 from "os";
|
|
5110
5127
|
import path23 from "path";
|
|
5111
5128
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
5112
5129
|
|
|
5113
5130
|
// packages/core/src/agent-models.ts
|
|
5114
|
-
import
|
|
5131
|
+
import fs14 from "fs";
|
|
5115
5132
|
import os5 from "os";
|
|
5116
5133
|
import path17 from "path";
|
|
5117
5134
|
|
|
5118
5135
|
// packages/core/src/claude-models.ts
|
|
5119
5136
|
init_effort();
|
|
5120
|
-
import
|
|
5137
|
+
import fs13 from "fs";
|
|
5121
5138
|
import os3 from "os";
|
|
5122
5139
|
import path16 from "path";
|
|
5123
5140
|
|
|
5124
5141
|
// packages/core/src/json-lines-process.ts
|
|
5125
|
-
init_env();
|
|
5126
5142
|
import { spawn as spawn4 } from "child_process";
|
|
5143
|
+
init_env();
|
|
5127
5144
|
function spawnJsonLines(bin, args, opts) {
|
|
5128
5145
|
const spawnOpts = { cwd: opts.cwd, env: opts.env ?? execEnv(), windowsHide: true };
|
|
5129
|
-
const proc = process.platform === "win32" ? spawn4([bin, ...args].join(" "), { ...spawnOpts, shell: true }) : spawn4(bin, args, spawnOpts);
|
|
5146
|
+
const proc = process.platform === "win32" ? spawn4([quoteWindowsBin(bin), ...args].join(" "), { ...spawnOpts, shell: true }) : spawn4(bin, args, spawnOpts);
|
|
5130
5147
|
const inbox = [];
|
|
5131
5148
|
const waiters = [];
|
|
5132
5149
|
let failure = null;
|
|
@@ -5223,11 +5240,11 @@ var CLAUDE_MODELS_TIMEOUT_MS = 15e3;
|
|
|
5223
5240
|
var REQUEST_ID = "vibeflow-models";
|
|
5224
5241
|
var CLAUDE_ARGS = ["-p", "--input-format", "stream-json", "--output-format", "stream-json", "--verbose"];
|
|
5225
5242
|
function openClaude() {
|
|
5226
|
-
const cwd =
|
|
5243
|
+
const cwd = fs13.mkdtempSync(path16.join(os3.tmpdir(), "vf-claude-models-"));
|
|
5227
5244
|
return spawnJsonLines("claude", CLAUDE_ARGS, {
|
|
5228
5245
|
cwd,
|
|
5229
5246
|
timeoutMs: CLAUDE_MODELS_TIMEOUT_MS,
|
|
5230
|
-
onExit: () =>
|
|
5247
|
+
onExit: () => fs13.rmSync(cwd, { recursive: true, force: true })
|
|
5231
5248
|
});
|
|
5232
5249
|
}
|
|
5233
5250
|
function isRecord(value) {
|
|
@@ -5404,7 +5421,7 @@ function errorMessage(err) {
|
|
|
5404
5421
|
async function readCodexCache(codexHome) {
|
|
5405
5422
|
const cachePath = path17.join(codexHome, "models_cache.json");
|
|
5406
5423
|
try {
|
|
5407
|
-
const raw = await
|
|
5424
|
+
const raw = await fs14.promises.readFile(cachePath, "utf8");
|
|
5408
5425
|
return { models: parseCodexCatalog(raw), source: "codex-cache" };
|
|
5409
5426
|
} catch (err) {
|
|
5410
5427
|
const missing = err.code === "ENOENT";
|
|
@@ -5526,7 +5543,7 @@ function effortDescription(level) {
|
|
|
5526
5543
|
}
|
|
5527
5544
|
|
|
5528
5545
|
// packages/core/src/jev-credentials.ts
|
|
5529
|
-
import
|
|
5546
|
+
import fs15 from "fs";
|
|
5530
5547
|
import path18 from "path";
|
|
5531
5548
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
5532
5549
|
function keyPath(dir) {
|
|
@@ -5538,8 +5555,8 @@ function dataDir() {
|
|
|
5538
5555
|
function readJevApiKey(dir = dataDir()) {
|
|
5539
5556
|
try {
|
|
5540
5557
|
const file = keyPath(dir);
|
|
5541
|
-
if (
|
|
5542
|
-
const saved =
|
|
5558
|
+
if (fs15.lstatSync(file).isSymbolicLink()) throw new Error("Jev key file must not be a symlink");
|
|
5559
|
+
const saved = fs15.readFileSync(file, "utf8").trim();
|
|
5543
5560
|
if (saved) return saved;
|
|
5544
5561
|
} catch (err) {
|
|
5545
5562
|
if (err.code !== "ENOENT") throw err;
|
|
@@ -5549,8 +5566,8 @@ function readJevApiKey(dir = dataDir()) {
|
|
|
5549
5566
|
function jevKeyStatus(dir = dataDir()) {
|
|
5550
5567
|
try {
|
|
5551
5568
|
const file = keyPath(dir);
|
|
5552
|
-
if (
|
|
5553
|
-
if (
|
|
5569
|
+
if (fs15.lstatSync(file).isSymbolicLink()) throw new Error("Jev key file must not be a symlink");
|
|
5570
|
+
if (fs15.readFileSync(file, "utf8").trim()) return { configured: true, source: "saved" };
|
|
5554
5571
|
} catch (err) {
|
|
5555
5572
|
if (err.code !== "ENOENT") throw err;
|
|
5556
5573
|
}
|
|
@@ -5561,20 +5578,20 @@ function saveJevApiKey(value, dir = dataDir()) {
|
|
|
5561
5578
|
if (!key || key.length > 4096 || !/^[\x21-\x7e]+$/.test(key)) {
|
|
5562
5579
|
throw new Error("Jev API key \u683C\u5F0F\u7121\u6548");
|
|
5563
5580
|
}
|
|
5564
|
-
|
|
5581
|
+
fs15.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
5565
5582
|
const file = keyPath(dir);
|
|
5566
5583
|
const tmp = `${file}.${randomUUID3()}.tmp`;
|
|
5567
5584
|
try {
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
if (process.platform !== "win32")
|
|
5585
|
+
fs15.writeFileSync(tmp, key, { mode: 384, flag: "wx" });
|
|
5586
|
+
fs15.renameSync(tmp, file);
|
|
5587
|
+
if (process.platform !== "win32") fs15.chmodSync(file, 384);
|
|
5571
5588
|
} finally {
|
|
5572
|
-
|
|
5589
|
+
fs15.rmSync(tmp, { force: true });
|
|
5573
5590
|
}
|
|
5574
5591
|
return { configured: true, source: "saved" };
|
|
5575
5592
|
}
|
|
5576
5593
|
function removeJevApiKey(dir = dataDir()) {
|
|
5577
|
-
|
|
5594
|
+
fs15.rmSync(keyPath(dir), { force: true });
|
|
5578
5595
|
return jevKeyStatus(dir);
|
|
5579
5596
|
}
|
|
5580
5597
|
|
|
@@ -5683,7 +5700,7 @@ function startGitHubCliLogin(onEvent) {
|
|
|
5683
5700
|
let proc;
|
|
5684
5701
|
try {
|
|
5685
5702
|
proc = nodePty3.spawn(
|
|
5686
|
-
"gh",
|
|
5703
|
+
resolvePtyFile("gh"),
|
|
5687
5704
|
["auth", "login", "--hostname", GITHUB_HOST, "--git-protocol", "https"],
|
|
5688
5705
|
{
|
|
5689
5706
|
name: "xterm-256color",
|
|
@@ -5870,10 +5887,11 @@ function startJiraLogin(onEvent, run3 = defaultAcliRunner) {
|
|
|
5870
5887
|
onEvent({ type: "starting" });
|
|
5871
5888
|
let process2;
|
|
5872
5889
|
try {
|
|
5873
|
-
|
|
5890
|
+
const env = { ...execEnv(), TERM: "xterm-256color" };
|
|
5891
|
+
process2 = nodePty4.spawn(resolvePtyFile("acli", env), ["jira", "auth", "login", "--web"], {
|
|
5874
5892
|
name: "xterm-256color",
|
|
5875
5893
|
cwd: processCwd(),
|
|
5876
|
-
env
|
|
5894
|
+
env,
|
|
5877
5895
|
cols: 100,
|
|
5878
5896
|
rows: 24
|
|
5879
5897
|
});
|
|
@@ -6085,23 +6103,23 @@ function createJiraService(options) {
|
|
|
6085
6103
|
}
|
|
6086
6104
|
|
|
6087
6105
|
// packages/core/src/board-cli.ts
|
|
6088
|
-
import
|
|
6106
|
+
import fs16 from "fs";
|
|
6089
6107
|
import path19 from "path";
|
|
6090
6108
|
import { pathToFileURL } from "url";
|
|
6091
6109
|
async function boardCliLaunchInfo() {
|
|
6092
6110
|
const storeDir = path19.dirname(getStorePath());
|
|
6093
6111
|
const entry = getPlatform().cliEntry?.();
|
|
6094
|
-
if (entry &&
|
|
6112
|
+
if (entry && fs16.existsSync(entry)) return { storeDir, cliPath: entry };
|
|
6095
6113
|
const root = getPlatform().sourceRoot();
|
|
6096
6114
|
if (!root) return { storeDir };
|
|
6097
6115
|
const cliPath = path19.join(root, "scripts", "vibeflow.mjs");
|
|
6098
6116
|
const loaderPath = path19.join(root, "test", "support", "register.mjs");
|
|
6099
|
-
if (!
|
|
6117
|
+
if (!fs16.existsSync(cliPath) || !fs16.existsSync(loaderPath)) return { storeDir };
|
|
6100
6118
|
return { storeDir, cliPath, loaderPath: pathToFileURL(loaderPath).href };
|
|
6101
6119
|
}
|
|
6102
6120
|
|
|
6103
6121
|
// packages/core/src/decisions.ts
|
|
6104
|
-
import
|
|
6122
|
+
import fs17 from "fs";
|
|
6105
6123
|
import path20 from "path";
|
|
6106
6124
|
var DECISIONS_FILE_SUFFIX = ".DECISIONS.md";
|
|
6107
6125
|
function decisionsKey(worktreePath, branch) {
|
|
@@ -6112,13 +6130,13 @@ function decisionsPath(workspacePath, key) {
|
|
|
6112
6130
|
}
|
|
6113
6131
|
function deleteDecisions(workspacePath, key) {
|
|
6114
6132
|
try {
|
|
6115
|
-
|
|
6133
|
+
fs17.rmSync(decisionsPath(workspacePath, key), { force: true });
|
|
6116
6134
|
} catch {
|
|
6117
6135
|
}
|
|
6118
6136
|
}
|
|
6119
6137
|
|
|
6120
6138
|
// packages/core/src/specs.ts
|
|
6121
|
-
import
|
|
6139
|
+
import fs18 from "fs";
|
|
6122
6140
|
import path21 from "path";
|
|
6123
6141
|
var SPEC_FILE_NAME = "spec.md";
|
|
6124
6142
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
@@ -6139,9 +6157,9 @@ async function readWorktreeSpecs(worktreePath, baseBranch) {
|
|
|
6139
6157
|
if (entry.status === "D" || !isSpecPath(entry.path)) continue;
|
|
6140
6158
|
try {
|
|
6141
6159
|
const full = path21.join(worktreePath, entry.path);
|
|
6142
|
-
const stat =
|
|
6160
|
+
const stat = fs18.statSync(full);
|
|
6143
6161
|
if (!stat.isFile()) continue;
|
|
6144
|
-
specs.push({ path: entry.path, ...clip2(
|
|
6162
|
+
specs.push({ path: entry.path, ...clip2(fs18.readFileSync(full)), updatedAt: stat.mtimeMs });
|
|
6145
6163
|
} catch {
|
|
6146
6164
|
}
|
|
6147
6165
|
}
|
|
@@ -6493,7 +6511,7 @@ init_launch();
|
|
|
6493
6511
|
// packages/core/src/progress-tracker.ts
|
|
6494
6512
|
init_progress();
|
|
6495
6513
|
init_launch();
|
|
6496
|
-
import
|
|
6514
|
+
import fs19 from "fs";
|
|
6497
6515
|
import os6 from "os";
|
|
6498
6516
|
import path22 from "path";
|
|
6499
6517
|
var SINCE_SLACK_MS = 5e3;
|
|
@@ -6503,7 +6521,7 @@ function claudeProjectDir(home, cwd) {
|
|
|
6503
6521
|
function pathAliases(p) {
|
|
6504
6522
|
const resolved = path22.resolve(p);
|
|
6505
6523
|
try {
|
|
6506
|
-
const real =
|
|
6524
|
+
const real = fs19.realpathSync(resolved);
|
|
6507
6525
|
return real === resolved ? [resolved] : [resolved, real];
|
|
6508
6526
|
} catch {
|
|
6509
6527
|
return [resolved];
|
|
@@ -6519,7 +6537,7 @@ function samePath(a, b) {
|
|
|
6519
6537
|
}
|
|
6520
6538
|
function listFiles(dir, test) {
|
|
6521
6539
|
try {
|
|
6522
|
-
return
|
|
6540
|
+
return fs19.readdirSync(dir).filter(test).map((name) => path22.join(dir, name));
|
|
6523
6541
|
} catch {
|
|
6524
6542
|
return [];
|
|
6525
6543
|
}
|
|
@@ -6527,22 +6545,22 @@ function listFiles(dir, test) {
|
|
|
6527
6545
|
function firstLine(file) {
|
|
6528
6546
|
let fd;
|
|
6529
6547
|
try {
|
|
6530
|
-
fd =
|
|
6548
|
+
fd = fs19.openSync(file, "r");
|
|
6531
6549
|
const buf = Buffer.alloc(64 * 1024);
|
|
6532
|
-
const n =
|
|
6550
|
+
const n = fs19.readSync(fd, buf, 0, buf.length, 0);
|
|
6533
6551
|
const text = buf.subarray(0, n).toString("utf8");
|
|
6534
6552
|
const nl = text.indexOf("\n");
|
|
6535
6553
|
return nl === -1 ? null : text.slice(0, nl);
|
|
6536
6554
|
} catch {
|
|
6537
6555
|
return null;
|
|
6538
6556
|
} finally {
|
|
6539
|
-
if (fd !== void 0)
|
|
6557
|
+
if (fd !== void 0) fs19.closeSync(fd);
|
|
6540
6558
|
}
|
|
6541
6559
|
}
|
|
6542
6560
|
function advance(file, cursor, reduce, initial) {
|
|
6543
6561
|
let size;
|
|
6544
6562
|
try {
|
|
6545
|
-
size =
|
|
6563
|
+
size = fs19.statSync(file).size;
|
|
6546
6564
|
} catch {
|
|
6547
6565
|
return;
|
|
6548
6566
|
}
|
|
@@ -6554,9 +6572,9 @@ function advance(file, cursor, reduce, initial) {
|
|
|
6554
6572
|
if (size === cursor.offset) return;
|
|
6555
6573
|
let fd;
|
|
6556
6574
|
try {
|
|
6557
|
-
fd =
|
|
6575
|
+
fd = fs19.openSync(file, "r");
|
|
6558
6576
|
const chunk = Buffer.alloc(size - cursor.offset);
|
|
6559
|
-
const n =
|
|
6577
|
+
const n = fs19.readSync(fd, chunk, 0, chunk.length, cursor.offset);
|
|
6560
6578
|
cursor.offset += n;
|
|
6561
6579
|
const data = Buffer.concat([cursor.rest, chunk.subarray(0, n)]);
|
|
6562
6580
|
const nl = data.lastIndexOf(10);
|
|
@@ -6570,7 +6588,7 @@ function advance(file, cursor, reduce, initial) {
|
|
|
6570
6588
|
}
|
|
6571
6589
|
} catch {
|
|
6572
6590
|
} finally {
|
|
6573
|
-
if (fd !== void 0)
|
|
6591
|
+
if (fd !== void 0) fs19.closeSync(fd);
|
|
6574
6592
|
}
|
|
6575
6593
|
}
|
|
6576
6594
|
function newCursor(state) {
|
|
@@ -6648,8 +6666,8 @@ function createProgressTracker(opts) {
|
|
|
6648
6666
|
const dir = path22.join(entry.target.worktreePath, PROGRESS_EVENTS_DIR);
|
|
6649
6667
|
for (const file of listFiles(dir, (n) => n.endsWith(".json")).sort()) {
|
|
6650
6668
|
try {
|
|
6651
|
-
const at =
|
|
6652
|
-
const event = JSON.parse(
|
|
6669
|
+
const at = fs19.statSync(file).mtimeMs;
|
|
6670
|
+
const event = JSON.parse(fs19.readFileSync(file, "utf8"));
|
|
6653
6671
|
const foreign = entry.target.sessionId && typeof event.session_id === "string" && event.session_id !== entry.target.sessionId;
|
|
6654
6672
|
const activity = foreign ? null : activityFromHook(event, at);
|
|
6655
6673
|
if (activity) entry.hookActivity = latestActivity(entry.hookActivity ?? activity, activity);
|
|
@@ -6657,7 +6675,7 @@ function createProgressTracker(opts) {
|
|
|
6657
6675
|
continue;
|
|
6658
6676
|
}
|
|
6659
6677
|
try {
|
|
6660
|
-
|
|
6678
|
+
fs19.unlinkSync(file);
|
|
6661
6679
|
} catch {
|
|
6662
6680
|
}
|
|
6663
6681
|
}
|
|
@@ -6751,8 +6769,8 @@ function createProgressTracker(opts) {
|
|
|
6751
6769
|
entries.set(target.taskId, entry);
|
|
6752
6770
|
const eventsDir = path22.join(target.worktreePath, PROGRESS_EVENTS_DIR);
|
|
6753
6771
|
try {
|
|
6754
|
-
|
|
6755
|
-
entry.watcher =
|
|
6772
|
+
fs19.mkdirSync(eventsDir, { recursive: true });
|
|
6773
|
+
entry.watcher = fs19.watch(eventsDir, () => {
|
|
6756
6774
|
if (entry.pending) return;
|
|
6757
6775
|
entry.pending = setTimeout(() => {
|
|
6758
6776
|
entry.pending = null;
|
|
@@ -7122,7 +7140,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
7122
7140
|
// `vibeflow open <path>` while a host runs: only the host writes the store.
|
|
7123
7141
|
"projects:record": (projectPath) => {
|
|
7124
7142
|
const p = path23.resolve(str(projectPath, "projectPath"));
|
|
7125
|
-
if (!
|
|
7143
|
+
if (!fs20.existsSync(p) || !fs20.statSync(p).isDirectory()) invalid(`not a directory: ${p}`);
|
|
7126
7144
|
recordRecentProject(getStore(), p);
|
|
7127
7145
|
return listRecentProjects(getStore());
|
|
7128
7146
|
},
|
|
@@ -7311,7 +7329,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
7311
7329
|
cwd = str(p.projectPath, "projectPath");
|
|
7312
7330
|
projectPath = cwd;
|
|
7313
7331
|
}
|
|
7314
|
-
if (!path23.isAbsolute(cwd) || !
|
|
7332
|
+
if (!path23.isAbsolute(cwd) || !fs20.existsSync(cwd) || !fs20.statSync(cwd).isDirectory()) {
|
|
7315
7333
|
invalid("terminal directory must be an existing absolute directory");
|
|
7316
7334
|
}
|
|
7317
7335
|
const title = (typeof p.title === "string" ? p.title.trim() : "") || saved?.title || path23.basename(projectPath);
|
|
@@ -7364,7 +7382,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
7364
7382
|
"claude:sessionExists": (taskId) => {
|
|
7365
7383
|
const task = requireTask(taskId);
|
|
7366
7384
|
if (!task.worktreePath) return false;
|
|
7367
|
-
return
|
|
7385
|
+
return fs20.existsSync(claudeSessionFile(task.worktreePath, executorSessionId(task.id, task.runId)));
|
|
7368
7386
|
},
|
|
7369
7387
|
"sessions:list": async () => {
|
|
7370
7388
|
const keys = await sessions.list();
|
|
@@ -7411,7 +7429,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
7411
7429
|
const task = requireTask(taskId);
|
|
7412
7430
|
if (!task.worktreePath || !task.workspacePath) return "task has no worktree";
|
|
7413
7431
|
const dir = agentArtifactsPath(task.workspacePath, task.worktreePath);
|
|
7414
|
-
if (!
|
|
7432
|
+
if (!fs20.existsSync(dir)) return "artifacts directory does not exist yet";
|
|
7415
7433
|
return getPlatform().openPath(dir);
|
|
7416
7434
|
},
|
|
7417
7435
|
"task:getSpecs": async (taskId) => {
|
|
@@ -7546,7 +7564,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
7546
7564
|
}
|
|
7547
7565
|
await removeTaskWorktree(task);
|
|
7548
7566
|
if (task.workspacePath) {
|
|
7549
|
-
|
|
7567
|
+
fs20.rmSync(taskAttachmentStagingPath(task.workspacePath, task.id), { recursive: true, force: true });
|
|
7550
7568
|
}
|
|
7551
7569
|
clearConversation(task.id);
|
|
7552
7570
|
removeTask(task.id);
|
|
@@ -7601,7 +7619,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
|
|
|
7601
7619
|
watchStore() {
|
|
7602
7620
|
const file = path23.basename(getStorePath());
|
|
7603
7621
|
let debounce = null;
|
|
7604
|
-
storeWatcher =
|
|
7622
|
+
storeWatcher = fs20.watch(path23.dirname(getStorePath()), (_event, filename) => {
|
|
7605
7623
|
if (filename !== file) return;
|
|
7606
7624
|
if (debounce) clearTimeout(debounce);
|
|
7607
7625
|
debounce = setTimeout(() => {
|
|
@@ -7638,7 +7656,7 @@ function createSessionBackend(sink, choice) {
|
|
|
7638
7656
|
}
|
|
7639
7657
|
|
|
7640
7658
|
// packages/core/src/web-server.ts
|
|
7641
|
-
import
|
|
7659
|
+
import fs21 from "fs";
|
|
7642
7660
|
import http from "http";
|
|
7643
7661
|
import path24 from "path";
|
|
7644
7662
|
import { timingSafeEqual } from "crypto";
|
|
@@ -7702,7 +7720,7 @@ function resolveStatic(root, urlPath) {
|
|
|
7702
7720
|
const full = path24.resolve(base2, c);
|
|
7703
7721
|
if (full !== base2 && !full.startsWith(base2 + path24.sep)) return null;
|
|
7704
7722
|
try {
|
|
7705
|
-
if (
|
|
7723
|
+
if (fs21.statSync(full).isFile()) return full;
|
|
7706
7724
|
} catch {
|
|
7707
7725
|
}
|
|
7708
7726
|
}
|
|
@@ -7776,7 +7794,7 @@ async function startWebServer(options) {
|
|
|
7776
7794
|
res.end();
|
|
7777
7795
|
return;
|
|
7778
7796
|
}
|
|
7779
|
-
|
|
7797
|
+
fs21.createReadStream(file).pipe(res);
|
|
7780
7798
|
}
|
|
7781
7799
|
const wss = new WebSocketServer({ noServer: true, maxPayload: MAX_PAYLOAD });
|
|
7782
7800
|
function reject(socket, status, reason) {
|
|
@@ -7875,7 +7893,7 @@ Content-Length: 0\r
|
|
|
7875
7893
|
}
|
|
7876
7894
|
|
|
7877
7895
|
// packages/cli/src/update-command.ts
|
|
7878
|
-
import
|
|
7896
|
+
import fs22 from "node:fs";
|
|
7879
7897
|
import path25 from "node:path";
|
|
7880
7898
|
import { spawnSync } from "node:child_process";
|
|
7881
7899
|
function npmRunner(args, inherit) {
|
|
@@ -7889,7 +7907,7 @@ function npmRunner(args, inherit) {
|
|
|
7889
7907
|
}
|
|
7890
7908
|
function packageName(packageRoot) {
|
|
7891
7909
|
try {
|
|
7892
|
-
const pkg = JSON.parse(
|
|
7910
|
+
const pkg = JSON.parse(fs22.readFileSync(path25.join(packageRoot, "package.json"), "utf8"));
|
|
7893
7911
|
if (typeof pkg.name !== "string") return null;
|
|
7894
7912
|
return /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(pkg.name) ? pkg.name : null;
|
|
7895
7913
|
} catch {
|
|
@@ -7917,7 +7935,7 @@ function runUpdate(options) {
|
|
|
7917
7935
|
}
|
|
7918
7936
|
try {
|
|
7919
7937
|
const globalPackage = path25.join(String(root.stdout).trim(), ...name.split("/"));
|
|
7920
|
-
if (
|
|
7938
|
+
if (fs22.lstatSync(globalPackage).isSymbolicLink() || fs22.realpathSync(globalPackage) !== fs22.realpathSync(packageRoot)) {
|
|
7921
7939
|
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");
|
|
7922
7940
|
return 1;
|
|
7923
7941
|
}
|
|
@@ -8063,7 +8081,7 @@ async function openUpdateTerminal(platform = process.platform, run3 = launch) {
|
|
|
8063
8081
|
}
|
|
8064
8082
|
|
|
8065
8083
|
// packages/cli/src/self-update.ts
|
|
8066
|
-
import
|
|
8084
|
+
import fs23 from "node:fs";
|
|
8067
8085
|
import path26 from "node:path";
|
|
8068
8086
|
import { execFile as execFile10 } from "node:child_process";
|
|
8069
8087
|
import { promisify as promisify7 } from "node:util";
|
|
@@ -8073,7 +8091,7 @@ var PROBE_RETRY_MS = 3e4;
|
|
|
8073
8091
|
var HOST_TOKEN_ENV = "VIBEFLOW_HOST_TOKEN";
|
|
8074
8092
|
function readInstalledVersion(packageRoot) {
|
|
8075
8093
|
try {
|
|
8076
|
-
const pkg = JSON.parse(
|
|
8094
|
+
const pkg = JSON.parse(fs23.readFileSync(path26.join(packageRoot, "package.json"), "utf8"));
|
|
8077
8095
|
return typeof pkg.version === "string" ? pkg.version : null;
|
|
8078
8096
|
} catch {
|
|
8079
8097
|
return null;
|
|
@@ -8257,7 +8275,7 @@ function loginUrl(lock, pathname = "/home/") {
|
|
|
8257
8275
|
return `http://127.0.0.1:${lock.port}${pathname}?token=${encodeURIComponent(lock.token)}`;
|
|
8258
8276
|
}
|
|
8259
8277
|
function isWebDir(dir) {
|
|
8260
|
-
return
|
|
8278
|
+
return fs24.existsSync(path27.join(dir, "home", "index.html"));
|
|
8261
8279
|
}
|
|
8262
8280
|
|
|
8263
8281
|
// packages/cli/src/remote.ts
|
|
@@ -8374,7 +8392,7 @@ function connectToHost(lock) {
|
|
|
8374
8392
|
}
|
|
8375
8393
|
|
|
8376
8394
|
// packages/cli/src/doctor.ts
|
|
8377
|
-
import
|
|
8395
|
+
import fs25 from "fs";
|
|
8378
8396
|
import path28 from "path";
|
|
8379
8397
|
import { execFile as execFile11 } from "child_process";
|
|
8380
8398
|
import { promisify as promisify8 } from "util";
|
|
@@ -8515,10 +8533,10 @@ async function runDoctor(options) {
|
|
|
8515
8533
|
});
|
|
8516
8534
|
}
|
|
8517
8535
|
try {
|
|
8518
|
-
|
|
8536
|
+
fs25.mkdirSync(options.userDataDir, { recursive: true });
|
|
8519
8537
|
const probe = path28.join(options.userDataDir, `.doctor-${process.pid}`);
|
|
8520
|
-
|
|
8521
|
-
|
|
8538
|
+
fs25.writeFileSync(probe, "");
|
|
8539
|
+
fs25.rmSync(probe);
|
|
8522
8540
|
checks.push({ id: "data", name: "\u8CC7\u6599\u76EE\u9304", level: "ok", detail: options.userDataDir });
|
|
8523
8541
|
} catch (err) {
|
|
8524
8542
|
checks.push({
|
|
@@ -8590,7 +8608,7 @@ function detectLayout() {
|
|
|
8590
8608
|
}
|
|
8591
8609
|
function readVersion(pkgPath) {
|
|
8592
8610
|
try {
|
|
8593
|
-
return JSON.parse(
|
|
8611
|
+
return JSON.parse(fs27.readFileSync(pkgPath, "utf8")).version;
|
|
8594
8612
|
} catch {
|
|
8595
8613
|
return "0.0.0";
|
|
8596
8614
|
}
|
|
@@ -8829,7 +8847,7 @@ async function cmdOpen(values, target, layout, userDataDir) {
|
|
|
8829
8847
|
return 1;
|
|
8830
8848
|
}
|
|
8831
8849
|
const dir = path31.resolve(target);
|
|
8832
|
-
if (!
|
|
8850
|
+
if (!fs27.existsSync(dir) || !fs27.statSync(dir).isDirectory()) {
|
|
8833
8851
|
console.error(`\u4E0D\u662F\u8CC7\u6599\u593E\uFF1A${dir}`);
|
|
8834
8852
|
return 1;
|
|
8835
8853
|
}
|
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=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.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-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/
|
|
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=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.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-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/wK5QA4FEMxOvUUnrrWMLN/_buildManifest.js" defer=""></script><script src="/_next/static/wK5QA4FEMxOvUUnrrWMLN/_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":"wK5QA4FEMxOvUUnrrWMLN","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=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.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-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/
|
|
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=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.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-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/wK5QA4FEMxOvUUnrrWMLN/_buildManifest.js" defer=""></script><script src="/_next/static/wK5QA4FEMxOvUUnrrWMLN/_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":"wK5QA4FEMxOvUUnrrWMLN","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
package/dist/web/home/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=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">VibeFlow</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.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-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/9296-f476f95a89709fef.js" defer=""></script><script src="/_next/static/chunks/pages/home-6422d9ccd1c4678c.js" defer=""></script><script src="/_next/static/
|
|
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=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">VibeFlow</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.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-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/9296-f476f95a89709fef.js" defer=""></script><script src="/_next/static/chunks/pages/home-6422d9ccd1c4678c.js" defer=""></script><script src="/_next/static/wK5QA4FEMxOvUUnrrWMLN/_buildManifest.js" defer=""></script><script src="/_next/static/wK5QA4FEMxOvUUnrrWMLN/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="bg-background text-foreground"><div class="flex min-h-screen items-center justify-center bg-background text-base text-muted-foreground">載入中…</div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/home","query":{},"buildId":"wK5QA4FEMxOvUUnrrWMLN","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
package/package.json
CHANGED
/package/dist/web/_next/static/{2-gox_m7xBQBsIihLK8dE → wK5QA4FEMxOvUUnrrWMLN}/_buildManifest.js
RENAMED
|
File without changes
|
/package/dist/web/_next/static/{2-gox_m7xBQBsIihLK8dE → wK5QA4FEMxOvUUnrrWMLN}/_ssgManifest.js
RENAMED
|
File without changes
|