@kw-yeh/vibeflow 4.11.23 → 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 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 fs3 from "fs";
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
- fs3.mkdirSync(this.logDir, { recursive: true });
361
- fs3.writeFileSync(this.confPath, TMUX_CONF);
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
- fs3.rmSync(this.statusPath(key), { force: true });
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(fs3.readFileSync(this.statusPath(key), "utf8").trim());
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;
@@ -611,7 +625,7 @@ function assembleCommand(agent, systemPrompt, prompt, model, effort, opts, workt
611
625
  const effortFlag = effort && effort !== "auto" ? ` --effort ${effort}` : "";
612
626
  const flags = `--chrome${claudePermissionFlag(opts?.autoMode)}${modelFlag}${effortFlag}${settings}${addDir}`;
613
627
  const sysFlag = systemPrompt ? ` --append-system-prompt ${shellQuote(systemPrompt)}` : "";
614
- const promptArg = prompt ? ` ${shellQuote(prompt)}` : "";
628
+ const promptArg = prompt ? ` -- ${shellQuote(prompt)}` : "";
615
629
  const tail = `${flags}${sysFlag}${promptArg}`;
616
630
  cmd = sessionId && opts?.resume ? claudeResumeOrFresh(sessionId, worktreePath, tail) : `claude ${sessionId ? `--session-id ${sessionId} ` : opts?.resume ? "--continue " : ""}${tail}\r`;
617
631
  } else {
@@ -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 fs6 from "fs";
697
+ import fs7 from "fs";
684
698
  import path10 from "path";
685
699
  function fileToAttachmentInput(filePath) {
686
- const bytes = fs6.readFileSync(filePath);
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 = fs6.existsSync(excludePath) ? fs6.readFileSync(excludePath, "utf8") : "";
738
+ const content = fs7.existsSync(excludePath) ? fs7.readFileSync(excludePath, "utf8") : "";
725
739
  if (!content.split(/\r?\n/).includes(entry)) {
726
- fs6.mkdirSync(path10.dirname(excludePath), { recursive: true });
727
- fs6.appendFileSync(excludePath, `
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
- fs6.mkdirSync(attachmentDir, { recursive: true });
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
- fs6.writeFileSync(filePath, bytes);
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 fs25 from "fs";
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 = fs25.mkdtempSync(path29.join(os8.tmpdir(), "vibeflow-"));
1238
+ const dir = fs26.mkdtempSync(path29.join(os8.tmpdir(), "vibeflow-"));
1225
1239
  const file = path29.join(dir, "description.md");
1226
1240
  try {
1227
- fs25.writeFileSync(file, text);
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: fs25.readFileSync(file, "utf8").replace(/\r?\n$/, "") };
1246
+ return { text: fs26.readFileSync(file, "utf8").replace(/\r?\n$/, "") };
1233
1247
  } finally {
1234
- fs25.rmSync(dir, { recursive: true, force: true });
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 (!fs25.existsSync(file) || !fs25.statSync(file).isFile()) {
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 fs26 from "fs";
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 fs4 from "fs";
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 = fs4.statSync(file);
2688
+ stat = fs5.statSync(file);
2675
2689
  } catch {
2676
2690
  continue;
2677
2691
  }
2678
2692
  try {
2679
- fs4.accessSync(file, fs4.constants.X_OK);
2693
+ fs5.accessSync(file, fs5.constants.X_OK);
2680
2694
  continue;
2681
2695
  } catch {
2682
2696
  }
2683
2697
  try {
2684
- fs4.chmodSync(file, stat.mode & 4095 | 73);
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 fs9 from "fs/promises";
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 fs8 from "fs/promises";
2828
+ import fs9 from "fs/promises";
2812
2829
 
2813
2830
  // packages/core/src/subagents.ts
2814
- import fs5 from "fs";
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
- fs5.rmSync(path9.join(cwd, SUBAGENTS_DIR), { recursive: true, force: true });
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 = fs5.readdirSync(dir).filter((n) => n.endsWith(".json"));
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 = fs5.readFileSync(path9.join(dir, name), "utf8");
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
- fs5.watchFile(dir, { interval: 800 }, sync);
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
- fs5.unwatchFile(entry.dir);
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 fs7 from "fs";
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
- fs7.mkdirSync(path11.join(dir, SCRATCH_DIR_NAME2), { recursive: true });
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 = fs7.lstatSync(source);
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
- fs7.copyFileSync(source, destination, fs7.constants.COPYFILE_EXCL);
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 = fs7.openSync(filePath, "r");
3386
+ fd = fs8.openSync(filePath, "r");
3370
3387
  const buf = Buffer.alloc(SNIFF_BYTES);
3371
- const read = fs7.readSync(fd, buf, 0, SNIFF_BYTES, 0);
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
- fs7.closeSync(fd);
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 = fs7.realpathSync(path11.resolve(dir));
3389
- target = fs7.realpathSync(path11.resolve(root, name));
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 = fs7.readdirSync(current, { withFileTypes: true });
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 = fs7.statSync(full);
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 = fs7.lstatSync(target);
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,${fs7.readFileSync(target).toString("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 = fs7.readFileSync(target);
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
- fs7.rmSync(agentArtifactsPath(baseDir, worktreePath), {
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 fs8.readFile(filePath, "utf8");
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 fs8.mkdir(path12.dirname(filePath), { recursive: true });
3571
+ await fs9.mkdir(path12.dirname(filePath), { recursive: true });
3555
3572
  }
3556
- await fs8.writeFile(filePath, content + addition, "utf8");
3573
+ await fs9.writeFile(filePath, content + addition, "utf8");
3557
3574
  }
3558
3575
  async function initRepository(projectPath) {
3559
- await fs8.mkdir(projectPath, { recursive: true });
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 fs8.access(path12.join(workspacePath, worktreeDirName(branch))).then(() => true).catch(() => false);
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 fs8.access(path12.join(workspacePath, worktreeDirName(preferredBranch))).then(() => true).catch(() => false);
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 fs8.lstat(current);
3756
+ const stat = await fs9.lstat(current);
3740
3757
  if (stat.isSymbolicLink()) continue;
3741
3758
  if (stat.isDirectory()) {
3742
- const children2 = await fs8.readdir(current, { withFileTypes: true });
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 fs8.mkdir(path12.dirname(dest), { recursive: true });
3788
- await fs8.cp(src, dest, {
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 fs8.lstat(from)).isSymbolicLink()) return true;
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 fs8.readlink(from)).replace(/^\\\\\?\\/, "");
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 fs8.stat(resolved)).isDirectory();
3822
+ isDirectory = (await fs9.stat(resolved)).isDirectory();
3806
3823
  } catch {
3807
3824
  return;
3808
3825
  }
3809
- await fs8.mkdir(path12.dirname(to), { recursive: true });
3826
+ await fs9.mkdir(path12.dirname(to), { recursive: true });
3810
3827
  if (process.platform !== "win32") {
3811
- await fs8.symlink(path12.isAbsolute(raw) ? target : raw, to);
3828
+ await fs9.symlink(path12.isAbsolute(raw) ? target : raw, to);
3812
3829
  return;
3813
3830
  }
3814
3831
  if (isDirectory) {
3815
- await fs8.symlink(target, to, "junction");
3832
+ await fs9.symlink(target, to, "junction");
3816
3833
  return;
3817
3834
  }
3818
3835
  try {
3819
- await fs8.symlink(target, to, "file");
3836
+ await fs9.symlink(target, to, "file");
3820
3837
  } catch {
3821
- await fs8.copyFile(resolved, to);
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 fs8.rm(path12.join(worktreePath, ARTIFACTS_FALLBACK_DIR2), {
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 fs8.stat(path12.join(worktreePath, entry.path));
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 fs8.readFile(path12.join(worktreePath, entry.path), "utf8");
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 fs9.access(projectPath);
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 fs9.mkdir(workspacePath, { recursive: true });
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 fs9.mkdir(task.workspacePath, { recursive: true });
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 fs23 from "fs";
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 fs11 from "fs";
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 fs10 from "fs";
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 = fs10.readFileSync(indexPath(root), "utf8");
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
- fs10.mkdirSync(root, { recursive: true });
4819
+ fs11.mkdirSync(root, { recursive: true });
4803
4820
  const file = indexPath(root);
4804
- if (indexIsCorrupt(root)) fs10.renameSync(file, `${file}.corrupt-${Date.now()}`);
4821
+ if (indexIsCorrupt(root)) fs11.renameSync(file, `${file}.corrupt-${Date.now()}`);
4805
4822
  const tmp = `${file}.${process.pid}.tmp`;
4806
- fs10.writeFileSync(tmp, `${JSON.stringify(index, null, 2)}
4823
+ fs11.writeFileSync(tmp, `${JSON.stringify(index, null, 2)}
4807
4824
  `);
4808
- fs10.renameSync(tmp, file);
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
- fs10.mkdirSync(path14.join(root, KIND_DIR[kind]), { recursive: true });
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 = fs10.readFileSync(skillMdPath, "utf8");
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 fs10.readdirSync(path14.join(dir, rel), { withFileTypes: true })) {
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 (fs10.statSync(path14.join(dir, child)).isDirectory()) walk(child);
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(fs10.readFileSync(path14.join(dir, rel))).update("\0");
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 (fs10.existsSync(path14.join(shipped, "SKILL.md"))) {
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 = fs10.readdirSync(dir, { withFileTypes: true });
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 = fs10.statSync(path14.join(dir, dirent.name));
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 && !fs10.existsSync(path14.join(full, "SKILL.md"))) continue;
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 = fs10.statSync(resolved);
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 (!fs10.existsSync(path14.join(resolved, "SKILL.md"))) {
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
- fs10.rmSync(target, { recursive: true, force: true });
4931
- fs10.cpSync(resolved, target, { recursive: kind === "skill", dereference: true });
4932
- if (kind === "script") fs10.chmodSync(target, 493);
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 (fs10.existsSync(target)) throw new Error(`\u5DF2\u5B58\u5728\u540C\u540D\u9805\u76EE\uFF1A${name}`);
4961
+ if (fs11.existsSync(target)) throw new Error(`\u5DF2\u5B58\u5728\u540C\u540D\u9805\u76EE\uFF1A${name}`);
4945
4962
  if (kind === "skill") {
4946
- fs10.mkdirSync(target, { recursive: true });
4947
- fs10.writeFileSync(path14.join(target, "SKILL.md"), content);
4963
+ fs11.mkdirSync(target, { recursive: true });
4964
+ fs11.writeFileSync(path14.join(target, "SKILL.md"), content);
4948
4965
  } else {
4949
- fs10.writeFileSync(target, content);
4950
- if (kind === "script") fs10.chmodSync(target, 493);
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 (!fs10.existsSync(target)) throw new Error(`\u627E\u4E0D\u5230\u9805\u76EE\uFF1A${name}`);
4965
- fs10.writeFileSync(kind === "skill" ? path14.join(target, "SKILL.md") : target, content);
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 fs10.readFileSync(kind === "skill" ? path14.join(target, "SKILL.md") : target, "utf8");
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
- fs10.rmSync(entryPath(root, kind, name), { recursive: true, force: true });
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 fs10.readdirSync(dir, { withFileTypes: true }).filter((d) => !d.name.startsWith(".")).map((d) => d.name).filter((name) => fs10.existsSync(path14.join(dir, name, "SKILL.md"))).sort();
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
- fs11.rmSync(staging, { recursive: true, force: true });
5029
+ fs12.rmSync(staging, { recursive: true, force: true });
5013
5030
  try {
5014
- fs11.cpSync(path15.join(builtinDir, name), staging, {
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
- fs11.rmSync(target, { recursive: true, force: true });
5020
- fs11.renameSync(staging, target);
5036
+ fs12.rmSync(target, { recursive: true, force: true });
5037
+ fs12.renameSync(staging, target);
5021
5038
  } finally {
5022
- fs11.rmSync(staging, { recursive: true, force: true });
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 (fs11.existsSync(target)) return;
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 (!fs11.existsSync(path15.join(target, "SKILL.md"))) {
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 (fs11.existsSync(entryPath(root, "skill", name)) && !readIndex(root).entries[key]?.builtinHash) {
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 && !fs11.existsSync(entryPath(root, "skill", name))
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 fs19 from "fs";
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 fs13 from "fs";
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 fs12 from "fs";
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 = fs12.mkdtempSync(path16.join(os3.tmpdir(), "vf-claude-models-"));
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: () => fs12.rmSync(cwd, { recursive: true, force: true })
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 fs13.promises.readFile(cachePath, "utf8");
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 fs14 from "fs";
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 (fs14.lstatSync(file).isSymbolicLink()) throw new Error("Jev key file must not be a symlink");
5542
- const saved = fs14.readFileSync(file, "utf8").trim();
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 (fs14.lstatSync(file).isSymbolicLink()) throw new Error("Jev key file must not be a symlink");
5553
- if (fs14.readFileSync(file, "utf8").trim()) return { configured: true, source: "saved" };
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
- fs14.mkdirSync(dir, { recursive: true, mode: 448 });
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
- fs14.writeFileSync(tmp, key, { mode: 384, flag: "wx" });
5569
- fs14.renameSync(tmp, file);
5570
- if (process.platform !== "win32") fs14.chmodSync(file, 384);
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
- fs14.rmSync(tmp, { force: true });
5589
+ fs15.rmSync(tmp, { force: true });
5573
5590
  }
5574
5591
  return { configured: true, source: "saved" };
5575
5592
  }
5576
5593
  function removeJevApiKey(dir = dataDir()) {
5577
- fs14.rmSync(keyPath(dir), { force: true });
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
- process2 = nodePty4.spawn("acli", ["jira", "auth", "login", "--web"], {
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: { ...execEnv(), TERM: "xterm-256color" },
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 fs15 from "fs";
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 && fs15.existsSync(entry)) return { storeDir, cliPath: 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 (!fs15.existsSync(cliPath) || !fs15.existsSync(loaderPath)) return { storeDir };
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 fs16 from "fs";
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
- fs16.rmSync(decisionsPath(workspacePath, key), { force: true });
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 fs17 from "fs";
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 = fs17.statSync(full);
6160
+ const stat = fs18.statSync(full);
6143
6161
  if (!stat.isFile()) continue;
6144
- specs.push({ path: entry.path, ...clip2(fs17.readFileSync(full)), updatedAt: stat.mtimeMs });
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 fs18 from "fs";
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 = fs18.realpathSync(resolved);
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 fs18.readdirSync(dir).filter(test).map((name) => path22.join(dir, name));
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 = fs18.openSync(file, "r");
6548
+ fd = fs19.openSync(file, "r");
6531
6549
  const buf = Buffer.alloc(64 * 1024);
6532
- const n = fs18.readSync(fd, buf, 0, buf.length, 0);
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) fs18.closeSync(fd);
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 = fs18.statSync(file).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 = fs18.openSync(file, "r");
6575
+ fd = fs19.openSync(file, "r");
6558
6576
  const chunk = Buffer.alloc(size - cursor.offset);
6559
- const n = fs18.readSync(fd, chunk, 0, chunk.length, cursor.offset);
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) fs18.closeSync(fd);
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 = fs18.statSync(file).mtimeMs;
6652
- const event = JSON.parse(fs18.readFileSync(file, "utf8"));
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
- fs18.unlinkSync(file);
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
- fs18.mkdirSync(eventsDir, { recursive: true });
6755
- entry.watcher = fs18.watch(eventsDir, () => {
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 (!fs19.existsSync(p) || !fs19.statSync(p).isDirectory()) invalid(`not a directory: ${p}`);
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) || !fs19.existsSync(cwd) || !fs19.statSync(cwd).isDirectory()) {
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 fs19.existsSync(claudeSessionFile(task.worktreePath, executorSessionId(task.id, task.runId)));
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 (!fs19.existsSync(dir)) return "artifacts directory does not exist yet";
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
- fs19.rmSync(taskAttachmentStagingPath(task.workspacePath, task.id), { recursive: true, force: true });
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 = fs19.watch(path23.dirname(getStorePath()), (_event, filename) => {
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 fs20 from "fs";
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 (fs20.statSync(full).isFile()) return full;
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
- fs20.createReadStream(file).pipe(res);
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 fs21 from "node:fs";
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(fs21.readFileSync(path25.join(packageRoot, "package.json"), "utf8"));
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 (fs21.lstatSync(globalPackage).isSymbolicLink() || fs21.realpathSync(globalPackage) !== fs21.realpathSync(packageRoot)) {
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 fs22 from "node:fs";
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(fs22.readFileSync(path26.join(packageRoot, "package.json"), "utf8"));
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 fs23.existsSync(path27.join(dir, "home", "index.html"));
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 fs24 from "fs";
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
- fs24.mkdirSync(options.userDataDir, { recursive: true });
8536
+ fs25.mkdirSync(options.userDataDir, { recursive: true });
8519
8537
  const probe = path28.join(options.userDataDir, `.doctor-${process.pid}`);
8520
- fs24.writeFileSync(probe, "");
8521
- fs24.rmSync(probe);
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(fs26.readFileSync(pkgPath, "utf8")).version;
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 (!fs26.existsSync(dir) || !fs26.statSync(dir).isDirectory()) {
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
  }
@@ -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/k4vs9Y-8Wd6zK6Ztl4X27/_buildManifest.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;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":"k4vs9Y-8Wd6zK6Ztl4X27","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
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,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;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/k4vs9Y-8Wd6zK6Ztl4X27/_buildManifest.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;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":"k4vs9Y-8Wd6zK6Ztl4X27","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
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,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;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>
@@ -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/k4vs9Y-8Wd6zK6Ztl4X27/_buildManifest.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_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":"k4vs9Y-8Wd6zK6Ztl4X27","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kw-yeh/vibeflow",
3
- "version": "4.11.23",
3
+ "version": "4.11.25",
4
4
  "description": "Intent-driven local kanban for coding agents: git worktree per card, Web UI and TUI.",
5
5
  "license": "MIT",
6
6
  "author": "KW-Yeh",