@kw-yeh/vibeflow 4.6.1 → 4.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/vibeflow.mjs +385 -69
- package/dist/web/404/index.html +1 -1
- package/dist/web/404.html +1 -1
- package/dist/web/_next/static/chunks/{8527-5442098d5121c96b.js → 7451-e9f74fece50504ed.js} +2 -2
- package/dist/web/_next/static/chunks/pages/{_app-d965862fbafe3116.js → _app-496c474d7f14dd07.js} +1 -1
- package/dist/web/_next/static/chunks/pages/home-78adf6369b572108.js +12 -0
- package/dist/web/_next/static/css/d25415d1bec170b4.css +2 -0
- package/dist/web/_next/static/{EJjFPosO-lar71yjnoaPb → rD1tZjqo_1oM7qAU7uvic}/_buildManifest.js +1 -1
- package/dist/web/home/index.html +1 -1
- package/package.json +1 -1
- package/dist/web/_next/static/chunks/pages/home-f31c4cf97ed808cf.js +0 -12
- package/dist/web/_next/static/css/7b78ec950bc90c91.css +0 -2
- /package/dist/web/_next/static/{EJjFPosO-lar71yjnoaPb → rD1tZjqo_1oM7qAU7uvic}/_ssgManifest.js +0 -0
package/dist/vibeflow.mjs
CHANGED
|
@@ -522,9 +522,9 @@ function truncateUtf8(value, maxBytes) {
|
|
|
522
522
|
return result;
|
|
523
523
|
}
|
|
524
524
|
function safeAttachmentName(name) {
|
|
525
|
-
const
|
|
525
|
+
const basename3 = name.replace(/\\/g, "/").split("/").pop() ?? "";
|
|
526
526
|
const sanitized = truncateUtf8(
|
|
527
|
-
|
|
527
|
+
basename3.replace(/[\u0000-\u001f\u007f]/g, "").trim(),
|
|
528
528
|
MAX_FILENAME_BYTES
|
|
529
529
|
);
|
|
530
530
|
return sanitized && sanitized !== "." && sanitized !== ".." ? sanitized : "attachment";
|
|
@@ -1333,8 +1333,8 @@ function quitHelp(backend, isHost) {
|
|
|
1333
1333
|
if (isHost) return "q \u96E2\u958B\uFF08\u9019\u500B TUI \u5C31\u662F host\uFF0C\u57F7\u884C\u4E2D\u7684 agent \u6703\u4E00\u8D77\u7D50\u675F\uFF09";
|
|
1334
1334
|
return "q \u96E2\u958B\uFF08agent \u7531\u57F7\u884C\u4E2D\u7684 host \u6301\u6709\uFF0C\u6703\u7E7C\u7E8C\u57F7\u884C\uFF09";
|
|
1335
1335
|
}
|
|
1336
|
-
function diffEnv(
|
|
1337
|
-
const env = { ...
|
|
1336
|
+
function diffEnv(base2, hasDelta) {
|
|
1337
|
+
const env = { ...base2 };
|
|
1338
1338
|
if (hasDelta) env.GIT_PAGER = "delta --side-by-side --paging=always";
|
|
1339
1339
|
else if (env.LESS === void 0) env.LESS = "R";
|
|
1340
1340
|
return env;
|
|
@@ -1607,9 +1607,9 @@ function hasCommand(cmd, args) {
|
|
|
1607
1607
|
return spawnSync2(cmd, args, { stdio: "ignore" }).status === 0;
|
|
1608
1608
|
}
|
|
1609
1609
|
function showDiff(task) {
|
|
1610
|
-
const
|
|
1610
|
+
const base2 = task.baseBranch ?? "HEAD";
|
|
1611
1611
|
const env = diffEnv(process.env, hasCommand("delta", ["--version"]));
|
|
1612
|
-
spawnSync2("git", ["-C", task.worktreePath, "-c", "color.ui=always", "diff",
|
|
1612
|
+
spawnSync2("git", ["-C", task.worktreePath, "-c", "color.ui=always", "diff", base2], {
|
|
1613
1613
|
stdio: "inherit",
|
|
1614
1614
|
env
|
|
1615
1615
|
});
|
|
@@ -2223,6 +2223,10 @@ function createBridge(t) {
|
|
|
2223
2223
|
startGithubAuthLogin: () => t.invoke("settings:startGithubAuthLogin"),
|
|
2224
2224
|
cancelGithubAuthLogin: () => t.invoke("settings:cancelGithubAuthLogin"),
|
|
2225
2225
|
logoutGithubAuth: () => t.invoke("settings:logoutGithubAuth"),
|
|
2226
|
+
/** Open Issues/PRs of the board's GitHub repos that involve me; cached unless `force`. */
|
|
2227
|
+
getGithubInbox: (opts) => t.invoke("github:inbox", opts ?? {}),
|
|
2228
|
+
/** The Issue/PR each card belongs to, keyed by task id. */
|
|
2229
|
+
getGithubTaskLinks: (opts) => t.invoke("github:taskLinks", opts ?? {}),
|
|
2226
2230
|
onGithubAuthEvent: (callback) => {
|
|
2227
2231
|
return t.on("github-auth:event", (payload) => callback(payload));
|
|
2228
2232
|
},
|
|
@@ -2533,8 +2537,8 @@ async function generateBranchName(title, description) {
|
|
|
2533
2537
|
}
|
|
2534
2538
|
|
|
2535
2539
|
// packages/core/src/git.ts
|
|
2536
|
-
import { execFile as
|
|
2537
|
-
import { promisify } from "util";
|
|
2540
|
+
import { execFile as execFile5 } from "child_process";
|
|
2541
|
+
import { promisify as promisify2 } from "util";
|
|
2538
2542
|
import path12 from "path";
|
|
2539
2543
|
import fs8 from "fs/promises";
|
|
2540
2544
|
|
|
@@ -2881,6 +2885,300 @@ function buildAgentCommand(task, systemPrompt, opts, workspacePath) {
|
|
|
2881
2885
|
|
|
2882
2886
|
// packages/core/src/git.ts
|
|
2883
2887
|
init_env();
|
|
2888
|
+
|
|
2889
|
+
// packages/core/src/github.ts
|
|
2890
|
+
init_env();
|
|
2891
|
+
import { execFile as execFile4 } from "child_process";
|
|
2892
|
+
import { promisify } from "util";
|
|
2893
|
+
var pexec = promisify(execFile4);
|
|
2894
|
+
var defaultGhRunner = async (args) => {
|
|
2895
|
+
const { stdout } = await pexec("gh", args, {
|
|
2896
|
+
env: execEnv(),
|
|
2897
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
2898
|
+
timeout: 3e4,
|
|
2899
|
+
windowsHide: true
|
|
2900
|
+
});
|
|
2901
|
+
return stdout.toString();
|
|
2902
|
+
};
|
|
2903
|
+
function parseGithubRepo(remoteUrl) {
|
|
2904
|
+
if (!remoteUrl) return null;
|
|
2905
|
+
const url = remoteUrl.trim();
|
|
2906
|
+
const match = url.match(/^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/) ?? url.match(/^ssh:\/\/git@github\.com(?::\d+)?\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/) ?? url.match(/^https?:\/\/(?:[^@/\s]+@)?github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/);
|
|
2907
|
+
return match ? `${match[1]}/${match[2]}` : null;
|
|
2908
|
+
}
|
|
2909
|
+
var REPO_RE = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
2910
|
+
function isGithubRef(value) {
|
|
2911
|
+
if (!value || typeof value !== "object") return false;
|
|
2912
|
+
const v = value;
|
|
2913
|
+
return (v.kind === "issue" || v.kind === "pr") && typeof v.repo === "string" && REPO_RE.test(v.repo) && typeof v.number === "number" && Number.isInteger(v.number) && v.number > 0 && typeof v.url === "string" && v.url.startsWith(`https://github.com/${v.repo}/`);
|
|
2914
|
+
}
|
|
2915
|
+
var ITEM_FIELDS = "number,title,url,body,author,assignees,labels,milestone,createdAt";
|
|
2916
|
+
var ISSUE_FIELDS = `${ITEM_FIELDS},issueType`;
|
|
2917
|
+
var PR_FIELDS = `${ITEM_FIELDS},state,isDraft,reviewDecision,headRefName,baseRefName`;
|
|
2918
|
+
var PR_INDEX_FIELDS = "number,url,state,isDraft,headRefName,closingIssuesReferences";
|
|
2919
|
+
var LIST_LIMIT = "50";
|
|
2920
|
+
var PR_INDEX_LIMIT = "100";
|
|
2921
|
+
async function runJson(run3, args) {
|
|
2922
|
+
const out = await run3(args);
|
|
2923
|
+
const parsed = JSON.parse(out || "[]");
|
|
2924
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
2925
|
+
}
|
|
2926
|
+
function user(raw) {
|
|
2927
|
+
const u = raw;
|
|
2928
|
+
if (!u || typeof u.login !== "string") return null;
|
|
2929
|
+
return typeof u.name === "string" && u.name ? { login: u.login, name: u.name } : { login: u.login };
|
|
2930
|
+
}
|
|
2931
|
+
function base(raw, repo) {
|
|
2932
|
+
const milestone = raw.milestone;
|
|
2933
|
+
return {
|
|
2934
|
+
repo,
|
|
2935
|
+
number: Number(raw.number),
|
|
2936
|
+
title: String(raw.title ?? ""),
|
|
2937
|
+
url: String(raw.url ?? ""),
|
|
2938
|
+
body: typeof raw.body === "string" ? raw.body : "",
|
|
2939
|
+
author: user(raw.author),
|
|
2940
|
+
assignees: Array.isArray(raw.assignees) ? raw.assignees.map(user).filter(Boolean) : [],
|
|
2941
|
+
labels: Array.isArray(raw.labels) ? raw.labels.map((l) => ({ name: String(l.name ?? ""), color: String(l.color ?? "") })) : [],
|
|
2942
|
+
milestone: milestone && typeof milestone.title === "string" ? milestone.title : null,
|
|
2943
|
+
createdAt: String(raw.createdAt ?? "")
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
function prStateOf(raw) {
|
|
2947
|
+
if (raw.state === "MERGED") return "merged";
|
|
2948
|
+
if (raw.state === "CLOSED") return "closed";
|
|
2949
|
+
return raw.isDraft ? "draft" : "open";
|
|
2950
|
+
}
|
|
2951
|
+
function toIssue(raw, repo) {
|
|
2952
|
+
const type = raw.issueType;
|
|
2953
|
+
return {
|
|
2954
|
+
...base(raw, repo),
|
|
2955
|
+
kind: "issue",
|
|
2956
|
+
issueType: type && typeof type.name === "string" ? { name: type.name, ...typeof type.color === "string" ? { color: type.color } : {} } : null
|
|
2957
|
+
};
|
|
2958
|
+
}
|
|
2959
|
+
function toPr(raw, repo) {
|
|
2960
|
+
return {
|
|
2961
|
+
...base(raw, repo),
|
|
2962
|
+
kind: "pr",
|
|
2963
|
+
state: prStateOf(raw),
|
|
2964
|
+
reviewDecision: typeof raw.reviewDecision === "string" && raw.reviewDecision ? raw.reviewDecision : null,
|
|
2965
|
+
headRefName: String(raw.headRefName ?? ""),
|
|
2966
|
+
baseRefName: String(raw.baseRefName ?? "")
|
|
2967
|
+
};
|
|
2968
|
+
}
|
|
2969
|
+
function mergeItems(lists) {
|
|
2970
|
+
const byNumber = /* @__PURE__ */ new Map();
|
|
2971
|
+
for (const list of lists) for (const item of list) if (!byNumber.has(item.number)) byNumber.set(item.number, item);
|
|
2972
|
+
return Array.from(byNumber.values()).sort(
|
|
2973
|
+
(a, b) => b.createdAt.localeCompare(a.createdAt) || b.number - a.number
|
|
2974
|
+
);
|
|
2975
|
+
}
|
|
2976
|
+
async function listIssues(run3, repo, filter) {
|
|
2977
|
+
const args = ["issue", "list", "-R", repo, "--state", "open", "--limit", LIST_LIMIT, ...filter];
|
|
2978
|
+
let rows;
|
|
2979
|
+
try {
|
|
2980
|
+
rows = await runJson(run3, [...args, "--json", ISSUE_FIELDS]);
|
|
2981
|
+
} catch (err) {
|
|
2982
|
+
if (!/issueType/.test(errorText(err))) throw err;
|
|
2983
|
+
rows = await runJson(run3, [...args, "--json", ITEM_FIELDS]);
|
|
2984
|
+
}
|
|
2985
|
+
return rows.map((r) => toIssue(r, repo));
|
|
2986
|
+
}
|
|
2987
|
+
async function listPrs(run3, repo, filter) {
|
|
2988
|
+
const rows = await runJson(run3, [
|
|
2989
|
+
"pr",
|
|
2990
|
+
"list",
|
|
2991
|
+
"-R",
|
|
2992
|
+
repo,
|
|
2993
|
+
"--state",
|
|
2994
|
+
"open",
|
|
2995
|
+
"--limit",
|
|
2996
|
+
LIST_LIMIT,
|
|
2997
|
+
...filter,
|
|
2998
|
+
"--json",
|
|
2999
|
+
PR_FIELDS
|
|
3000
|
+
]);
|
|
3001
|
+
return rows.map((r) => toPr(r, repo));
|
|
3002
|
+
}
|
|
3003
|
+
async function fetchRepoItems(run3, repo) {
|
|
3004
|
+
const [assignedIssues, authoredIssues, assignedPrs, authoredPrs, reviewPrs] = await Promise.all([
|
|
3005
|
+
listIssues(run3, repo, ["--assignee", "@me"]),
|
|
3006
|
+
listIssues(run3, repo, ["--author", "@me"]),
|
|
3007
|
+
listPrs(run3, repo, ["--assignee", "@me"]),
|
|
3008
|
+
listPrs(run3, repo, ["--author", "@me"]),
|
|
3009
|
+
listPrs(run3, repo, ["--search", "review-requested:@me"])
|
|
3010
|
+
]);
|
|
3011
|
+
return {
|
|
3012
|
+
issues: mergeItems([assignedIssues, authoredIssues]),
|
|
3013
|
+
prs: mergeItems([assignedPrs, authoredPrs, reviewPrs])
|
|
3014
|
+
};
|
|
3015
|
+
}
|
|
3016
|
+
async function fetchPrIndex(run3, repo) {
|
|
3017
|
+
const rows = await runJson(run3, [
|
|
3018
|
+
"pr",
|
|
3019
|
+
"list",
|
|
3020
|
+
"-R",
|
|
3021
|
+
repo,
|
|
3022
|
+
"--state",
|
|
3023
|
+
"all",
|
|
3024
|
+
"--limit",
|
|
3025
|
+
PR_INDEX_LIMIT,
|
|
3026
|
+
"--json",
|
|
3027
|
+
PR_INDEX_FIELDS
|
|
3028
|
+
]);
|
|
3029
|
+
const [owner, name] = repo.split("/");
|
|
3030
|
+
return rows.map((r) => ({
|
|
3031
|
+
number: Number(r.number),
|
|
3032
|
+
url: String(r.url ?? ""),
|
|
3033
|
+
state: prStateOf(r),
|
|
3034
|
+
headRefName: String(r.headRefName ?? ""),
|
|
3035
|
+
closingIssues: (Array.isArray(r.closingIssuesReferences) ? r.closingIssuesReferences : []).filter((ref) => {
|
|
3036
|
+
const repository = ref.repository;
|
|
3037
|
+
const refOwner = repository?.owner?.login;
|
|
3038
|
+
return !repository || repository.name === name && refOwner === owner;
|
|
3039
|
+
}).map((ref) => ({
|
|
3040
|
+
number: Number(ref.number),
|
|
3041
|
+
url: typeof ref.url === "string" ? ref.url : `https://github.com/${repo}/issues/${ref.number}`
|
|
3042
|
+
}))
|
|
3043
|
+
}));
|
|
3044
|
+
}
|
|
3045
|
+
function linkFromRef(ref, state) {
|
|
3046
|
+
return { kind: ref.kind, number: ref.number, url: ref.url, state };
|
|
3047
|
+
}
|
|
3048
|
+
function hasRealBranch(task) {
|
|
3049
|
+
return Boolean(task.provisionedAt || task.worktreePath || task.outcome);
|
|
3050
|
+
}
|
|
3051
|
+
function resolveTaskLinks(tasks, repoOfProject, prIndex) {
|
|
3052
|
+
const links = {};
|
|
3053
|
+
for (const task of tasks) {
|
|
3054
|
+
const source = task.github;
|
|
3055
|
+
const repo = source?.repo ?? (task.projectPath ? repoOfProject.get(task.projectPath) : void 0);
|
|
3056
|
+
const index = repo ? prIndex.get(repo) ?? [] : [];
|
|
3057
|
+
let pr;
|
|
3058
|
+
let prEntry;
|
|
3059
|
+
if (source?.kind === "pr") {
|
|
3060
|
+
prEntry = index.find((e) => e.number === source.number);
|
|
3061
|
+
pr = linkFromRef(source, prEntry?.state ?? "open");
|
|
3062
|
+
} else {
|
|
3063
|
+
if (hasRealBranch(task)) {
|
|
3064
|
+
prEntry = index.filter((e) => e.headRefName === task.branch).sort((a, b) => b.number - a.number)[0];
|
|
3065
|
+
}
|
|
3066
|
+
if (prEntry) {
|
|
3067
|
+
pr = { kind: "pr", number: prEntry.number, url: prEntry.url, state: prEntry.state };
|
|
3068
|
+
} else if (task.outcome?.pr) {
|
|
3069
|
+
const o = task.outcome.pr;
|
|
3070
|
+
pr = { kind: "pr", number: o.number, url: o.url, state: prStateOf({ state: o.state }) };
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
const issueState = pr?.state === "merged" ? "closed" : "open";
|
|
3074
|
+
let issue;
|
|
3075
|
+
if (source?.kind === "issue") {
|
|
3076
|
+
issue = linkFromRef(source, issueState);
|
|
3077
|
+
} else if (prEntry?.closingIssues[0]) {
|
|
3078
|
+
const ref = prEntry.closingIssues[0];
|
|
3079
|
+
issue = { kind: "issue", number: ref.number, url: ref.url, state: issueState };
|
|
3080
|
+
}
|
|
3081
|
+
if (pr || issue) links[task.id] = { ...issue ? { issue } : {}, ...pr ? { pr } : {} };
|
|
3082
|
+
}
|
|
3083
|
+
return links;
|
|
3084
|
+
}
|
|
3085
|
+
function errorText(err) {
|
|
3086
|
+
const e = err;
|
|
3087
|
+
const stderr = e?.stderr ? e.stderr.toString().trim() : "";
|
|
3088
|
+
return stderr || e?.message || String(err);
|
|
3089
|
+
}
|
|
3090
|
+
var GITHUB_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
3091
|
+
function boardTasks(board) {
|
|
3092
|
+
return [...board.in_progress, ...board.backlog, ...board.done];
|
|
3093
|
+
}
|
|
3094
|
+
function boardProjects(board) {
|
|
3095
|
+
const latest = /* @__PURE__ */ new Map();
|
|
3096
|
+
for (const t of boardTasks(board)) {
|
|
3097
|
+
if (!t.projectPath) continue;
|
|
3098
|
+
latest.set(t.projectPath, Math.max(latest.get(t.projectPath) ?? 0, t.createdAt ?? 0));
|
|
3099
|
+
}
|
|
3100
|
+
return Array.from(latest.entries()).sort((a, b) => b[1] - a[1]).map(([p]) => p);
|
|
3101
|
+
}
|
|
3102
|
+
function basename(p) {
|
|
3103
|
+
return p.split(/[/\\]/).filter(Boolean).pop() ?? p;
|
|
3104
|
+
}
|
|
3105
|
+
function createGithubService(options) {
|
|
3106
|
+
const run3 = options.run ?? defaultGhRunner;
|
|
3107
|
+
const authStatus = options.authStatus;
|
|
3108
|
+
const now = options.now ?? Date.now;
|
|
3109
|
+
const items = /* @__PURE__ */ new Map();
|
|
3110
|
+
const indexes = /* @__PURE__ */ new Map();
|
|
3111
|
+
const repos = /* @__PURE__ */ new Map();
|
|
3112
|
+
function cached2(map, key, force, load) {
|
|
3113
|
+
const hit = map.get(key);
|
|
3114
|
+
if (hit && !force && now() - hit.at < GITHUB_CACHE_TTL_MS) return hit;
|
|
3115
|
+
const entry = { at: now(), value: load() };
|
|
3116
|
+
entry.value.catch(() => {
|
|
3117
|
+
});
|
|
3118
|
+
map.set(key, entry);
|
|
3119
|
+
return entry;
|
|
3120
|
+
}
|
|
3121
|
+
async function projectRepos(board, force) {
|
|
3122
|
+
const out = /* @__PURE__ */ new Map();
|
|
3123
|
+
const projects = boardProjects(board);
|
|
3124
|
+
const resolved = await Promise.all(
|
|
3125
|
+
projects.map((p) => cached2(repos, p, force, () => options.repoOf(p)).value.catch(() => null))
|
|
3126
|
+
);
|
|
3127
|
+
projects.forEach((p, i) => {
|
|
3128
|
+
const repo = resolved[i];
|
|
3129
|
+
if (repo) out.set(p, repo);
|
|
3130
|
+
});
|
|
3131
|
+
return out;
|
|
3132
|
+
}
|
|
3133
|
+
return {
|
|
3134
|
+
async inbox(board, opts = {}) {
|
|
3135
|
+
const force = opts.force === true;
|
|
3136
|
+
const auth = await authStatus();
|
|
3137
|
+
if (!auth.installed) return { status: "gh-missing", fetchedAt: 0, repos: [] };
|
|
3138
|
+
if (!auth.authenticated) return { status: "unauthenticated", fetchedAt: 0, repos: [] };
|
|
3139
|
+
const byProject = await projectRepos(board, force);
|
|
3140
|
+
const repoProject = /* @__PURE__ */ new Map();
|
|
3141
|
+
for (const [project, repo] of byProject) if (!repoProject.has(repo)) repoProject.set(repo, project);
|
|
3142
|
+
const entries = Array.from(repoProject.entries());
|
|
3143
|
+
const results = await Promise.all(
|
|
3144
|
+
entries.map(async ([repo, projectPath]) => {
|
|
3145
|
+
const entry = cached2(items, repo, force, () => fetchRepoItems(run3, repo));
|
|
3146
|
+
const head = { repo, projectPath, projectName: basename(projectPath) };
|
|
3147
|
+
try {
|
|
3148
|
+
return { at: entry.at, inbox: { ...head, ...await entry.value } };
|
|
3149
|
+
} catch (err) {
|
|
3150
|
+
return { at: entry.at, inbox: { ...head, issues: [], prs: [], error: errorText(err) } };
|
|
3151
|
+
}
|
|
3152
|
+
})
|
|
3153
|
+
);
|
|
3154
|
+
return {
|
|
3155
|
+
status: "ok",
|
|
3156
|
+
...auth.login ? { login: auth.login } : {},
|
|
3157
|
+
fetchedAt: results.length ? Math.min(...results.map((r) => r.at)) : 0,
|
|
3158
|
+
repos: results.map((r) => r.inbox).sort((a, b) => a.repo.localeCompare(b.repo))
|
|
3159
|
+
};
|
|
3160
|
+
},
|
|
3161
|
+
async taskLinks(board, opts = {}) {
|
|
3162
|
+
const force = opts.force === true;
|
|
3163
|
+
const tasks = boardTasks(board);
|
|
3164
|
+
const byProject = await projectRepos(board, force);
|
|
3165
|
+
const wanted = new Set(byProject.values());
|
|
3166
|
+
for (const t of tasks) if (t.github) wanted.add(t.github.repo);
|
|
3167
|
+
const prIndex = /* @__PURE__ */ new Map();
|
|
3168
|
+
await Promise.all(
|
|
3169
|
+
Array.from(wanted).map(async (repo) => {
|
|
3170
|
+
try {
|
|
3171
|
+
prIndex.set(repo, await cached2(indexes, repo, force, () => fetchPrIndex(run3, repo)).value);
|
|
3172
|
+
} catch {
|
|
3173
|
+
}
|
|
3174
|
+
})
|
|
3175
|
+
);
|
|
3176
|
+
return resolveTaskLinks(tasks, byProject, prIndex);
|
|
3177
|
+
}
|
|
3178
|
+
};
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
// packages/core/src/git.ts
|
|
2884
3182
|
init_attachments();
|
|
2885
3183
|
|
|
2886
3184
|
// packages/core/src/artifacts.ts
|
|
@@ -3038,9 +3336,9 @@ function deleteArtifacts(baseDir, worktreePath) {
|
|
|
3038
3336
|
}
|
|
3039
3337
|
|
|
3040
3338
|
// packages/core/src/git.ts
|
|
3041
|
-
var
|
|
3339
|
+
var pexec2 = promisify2(execFile5);
|
|
3042
3340
|
async function git(cwd, args) {
|
|
3043
|
-
const { stdout } = await
|
|
3341
|
+
const { stdout } = await pexec2("git", args, {
|
|
3044
3342
|
cwd,
|
|
3045
3343
|
maxBuffer: 32 * 1024 * 1024,
|
|
3046
3344
|
env: execEnv()
|
|
@@ -3409,7 +3707,7 @@ function copyIgnoredDependenciesInBackground(projectPath, worktreePath, entries)
|
|
|
3409
3707
|
}
|
|
3410
3708
|
})();
|
|
3411
3709
|
}
|
|
3412
|
-
async function adoptRemoteBranch(projectPath, worktreePath, branch,
|
|
3710
|
+
async function adoptRemoteBranch(projectPath, worktreePath, branch, base2) {
|
|
3413
3711
|
try {
|
|
3414
3712
|
await git(projectPath, ["fetch", "origin", branch]);
|
|
3415
3713
|
} catch {
|
|
@@ -3431,32 +3729,32 @@ async function adoptRemoteBranch(projectPath, worktreePath, branch, base) {
|
|
|
3431
3729
|
}
|
|
3432
3730
|
const ignoredEntries = await copySmallIgnoredFiles(projectPath, worktreePath);
|
|
3433
3731
|
copyIgnoredDependenciesInBackground(projectPath, worktreePath, ignoredEntries);
|
|
3434
|
-
return { branch, worktreePath, pushed: true, baseBranch:
|
|
3732
|
+
return { branch, worktreePath, pushed: true, baseBranch: base2 };
|
|
3435
3733
|
}
|
|
3436
3734
|
async function provisionWorktree(projectPath, workspacePath, taskId, baseBranch, preferredBranch, opts = {}) {
|
|
3437
3735
|
await ensureLocalExclude(projectPath);
|
|
3438
3736
|
const branch = opts.explicitBranch && preferredBranch ? preferredBranch : await resolveBranchName(projectPath, workspacePath, taskId, preferredBranch);
|
|
3439
3737
|
const worktreePath = path12.join(workspacePath, worktreeDirName(branch));
|
|
3440
3738
|
const info = await getGitInfo(projectPath);
|
|
3441
|
-
const
|
|
3739
|
+
const base2 = baseBranch || info.defaultBase || info.currentBranch || "HEAD";
|
|
3442
3740
|
if (opts.explicitBranch && info.hasRemote && await remoteBranchExists(projectPath, branch)) {
|
|
3443
|
-
return adoptRemoteBranch(projectPath, worktreePath, branch,
|
|
3741
|
+
return adoptRemoteBranch(projectPath, worktreePath, branch, base2);
|
|
3444
3742
|
}
|
|
3445
|
-
let startPoint =
|
|
3743
|
+
let startPoint = base2;
|
|
3446
3744
|
if (info.hasRemote) {
|
|
3447
3745
|
try {
|
|
3448
|
-
await git(projectPath, ["fetch", "origin", `${
|
|
3746
|
+
await git(projectPath, ["fetch", "origin", `${base2}:${base2}`]);
|
|
3449
3747
|
} catch {
|
|
3450
3748
|
try {
|
|
3451
|
-
await git(projectPath, ["fetch", "origin",
|
|
3749
|
+
await git(projectPath, ["fetch", "origin", base2]);
|
|
3452
3750
|
} catch {
|
|
3453
3751
|
}
|
|
3454
3752
|
}
|
|
3455
3753
|
try {
|
|
3456
|
-
await git(projectPath, ["rev-parse", "--verify", `origin/${
|
|
3457
|
-
startPoint = `origin/${
|
|
3754
|
+
await git(projectPath, ["rev-parse", "--verify", `origin/${base2}`]);
|
|
3755
|
+
startPoint = `origin/${base2}`;
|
|
3458
3756
|
} catch {
|
|
3459
|
-
startPoint =
|
|
3757
|
+
startPoint = base2;
|
|
3460
3758
|
}
|
|
3461
3759
|
}
|
|
3462
3760
|
try {
|
|
@@ -3486,7 +3784,7 @@ async function provisionWorktree(projectPath, workspacePath, taskId, baseBranch,
|
|
|
3486
3784
|
copySmallIgnoredFiles(projectPath, worktreePath)
|
|
3487
3785
|
]);
|
|
3488
3786
|
copyIgnoredDependenciesInBackground(projectPath, worktreePath, ignoredEntries);
|
|
3489
|
-
return { branch, worktreePath, pushed, baseBranch:
|
|
3787
|
+
return { branch, worktreePath, pushed, baseBranch: base2 };
|
|
3490
3788
|
}
|
|
3491
3789
|
async function removeWorktree(projectPath, worktreePath) {
|
|
3492
3790
|
try {
|
|
@@ -3698,7 +3996,7 @@ var MAX_OUTCOME_COMMITS = 50;
|
|
|
3698
3996
|
var OUTCOME_LOG_FORMAT = "%h%x00%s";
|
|
3699
3997
|
async function getOutcomePr(worktreePath) {
|
|
3700
3998
|
try {
|
|
3701
|
-
const { stdout } = await
|
|
3999
|
+
const { stdout } = await pexec2(
|
|
3702
4000
|
"gh",
|
|
3703
4001
|
["pr", "view", "--json", "url,number,state,title,body"],
|
|
3704
4002
|
{ cwd: worktreePath, env: execEnv() }
|
|
@@ -3759,7 +4057,7 @@ async function captureTaskOutcome(worktreePath, baseBranch) {
|
|
|
3759
4057
|
}
|
|
3760
4058
|
async function getPrStatus(worktreePath) {
|
|
3761
4059
|
try {
|
|
3762
|
-
const { stdout } = await
|
|
4060
|
+
const { stdout } = await pexec2(
|
|
3763
4061
|
"gh",
|
|
3764
4062
|
["pr", "view", "--json", "url,number,state"],
|
|
3765
4063
|
{ cwd: worktreePath, env: execEnv() }
|
|
@@ -3775,17 +4073,9 @@ async function getGithubCompareUrl(worktreePath, baseBranch) {
|
|
|
3775
4073
|
try {
|
|
3776
4074
|
const remoteUrl = await git(worktreePath, ["remote", "get-url", "origin"]);
|
|
3777
4075
|
const branch = await git(worktreePath, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
if (sshMatch) {
|
|
3782
|
-
webUrl = `https://github.com/${sshMatch[1]}`;
|
|
3783
|
-
} else if (httpsMatch) {
|
|
3784
|
-
webUrl = `https://github.com/${httpsMatch[1]}`;
|
|
3785
|
-
} else {
|
|
3786
|
-
return null;
|
|
3787
|
-
}
|
|
3788
|
-
return `${webUrl}/compare/${baseBranch}...${branch}?expand=1`;
|
|
4076
|
+
const repo = parseGithubRepo(remoteUrl);
|
|
4077
|
+
if (!repo) return null;
|
|
4078
|
+
return `https://github.com/${repo}/compare/${baseBranch}...${branch}?expand=1`;
|
|
3789
4079
|
} catch {
|
|
3790
4080
|
return null;
|
|
3791
4081
|
}
|
|
@@ -3852,9 +4142,9 @@ function taskAttachmentStagingPath(workspacePath, taskId) {
|
|
|
3852
4142
|
|
|
3853
4143
|
// packages/core/src/agents.ts
|
|
3854
4144
|
init_env();
|
|
3855
|
-
import { execFile as
|
|
3856
|
-
import { promisify as
|
|
3857
|
-
var
|
|
4145
|
+
import { execFile as execFile6 } from "child_process";
|
|
4146
|
+
import { promisify as promisify3 } from "util";
|
|
4147
|
+
var pexec3 = promisify3(execFile6);
|
|
3858
4148
|
var AGENT_EFFORTS = ["low", "medium", "high", "xhigh"];
|
|
3859
4149
|
var DEFAULT_TASK_EFFORT = "medium";
|
|
3860
4150
|
var AGENT_CLIS = [
|
|
@@ -3882,7 +4172,7 @@ var AGENT_CLIS = [
|
|
|
3882
4172
|
async function commandExists(bin) {
|
|
3883
4173
|
try {
|
|
3884
4174
|
const command = process.platform === "win32" ? "where.exe" : "which";
|
|
3885
|
-
await
|
|
4175
|
+
await pexec3(command, [bin], {
|
|
3886
4176
|
env: execEnv(),
|
|
3887
4177
|
timeout: 2500,
|
|
3888
4178
|
windowsHide: true
|
|
@@ -3957,7 +4247,8 @@ async function createTaskFromInput(input) {
|
|
|
3957
4247
|
agentCli: input.agentCli ?? "claude",
|
|
3958
4248
|
model: input.model || void 0,
|
|
3959
4249
|
effort: input.effort ?? DEFAULT_TASK_EFFORT,
|
|
3960
|
-
autoMode: input.autoMode
|
|
4250
|
+
autoMode: input.autoMode,
|
|
4251
|
+
...input.github ? { github: input.github } : {}
|
|
3961
4252
|
};
|
|
3962
4253
|
try {
|
|
3963
4254
|
const board = store.get("board");
|
|
@@ -4311,9 +4602,9 @@ function truncateUtf82(value, maxBytes) {
|
|
|
4311
4602
|
return result;
|
|
4312
4603
|
}
|
|
4313
4604
|
function safeLibraryName(name) {
|
|
4314
|
-
const
|
|
4605
|
+
const basename3 = name.replace(/\\/g, "/").split("/").pop() ?? "";
|
|
4315
4606
|
const cleaned = truncateUtf82(
|
|
4316
|
-
|
|
4607
|
+
basename3.replace(/[\u0000-\u001f\u007f]/g, "").trim(),
|
|
4317
4608
|
MAX_NAME_BYTES
|
|
4318
4609
|
);
|
|
4319
4610
|
return cleaned && cleaned !== "." && cleaned !== ".." ? cleaned : "untitled";
|
|
@@ -4789,13 +5080,13 @@ import path21 from "path";
|
|
|
4789
5080
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
4790
5081
|
|
|
4791
5082
|
// packages/core/src/agent-models.ts
|
|
4792
|
-
import { execFile as
|
|
5083
|
+
import { execFile as execFile7 } from "child_process";
|
|
4793
5084
|
import fs12 from "fs";
|
|
4794
5085
|
import os4 from "os";
|
|
4795
5086
|
import path16 from "path";
|
|
4796
|
-
import { promisify as
|
|
5087
|
+
import { promisify as promisify4 } from "util";
|
|
4797
5088
|
init_env();
|
|
4798
|
-
var
|
|
5089
|
+
var pexec4 = promisify4(execFile7);
|
|
4799
5090
|
var CODEX_MODELS_TIMEOUT_MS = 2e4;
|
|
4800
5091
|
function builtinModels(id) {
|
|
4801
5092
|
return (AGENT_CLIS.find((a) => a.id === id) ?? AGENT_CLIS[0]).models;
|
|
@@ -4805,7 +5096,7 @@ function defaultCodexHome() {
|
|
|
4805
5096
|
return configured ? configured : path16.join(os4.homedir(), ".codex");
|
|
4806
5097
|
}
|
|
4807
5098
|
async function defaultRunCodexModels() {
|
|
4808
|
-
const { stdout } = await
|
|
5099
|
+
const { stdout } = await pexec4("codex", ["debug", "models"], {
|
|
4809
5100
|
env: execEnv(),
|
|
4810
5101
|
timeout: CODEX_MODELS_TIMEOUT_MS,
|
|
4811
5102
|
maxBuffer: 16 * 1024 * 1024,
|
|
@@ -4862,10 +5153,10 @@ async function listAgentModels(id, opts = {}) {
|
|
|
4862
5153
|
|
|
4863
5154
|
// packages/core/src/github-auth.ts
|
|
4864
5155
|
init_env();
|
|
4865
|
-
import { execFile as
|
|
4866
|
-
import { promisify as
|
|
5156
|
+
import { execFile as execFile8 } from "child_process";
|
|
5157
|
+
import { promisify as promisify5 } from "util";
|
|
4867
5158
|
import * as nodePty3 from "node-pty";
|
|
4868
|
-
var
|
|
5159
|
+
var pexec5 = promisify5(execFile8);
|
|
4869
5160
|
var GITHUB_HOST = "github.com";
|
|
4870
5161
|
var DEVICE_URL = "https://github.com/login/device";
|
|
4871
5162
|
var activeLogin = null;
|
|
@@ -4900,7 +5191,7 @@ function errorMessage2(err) {
|
|
|
4900
5191
|
}
|
|
4901
5192
|
async function getGitHubCliAuthStatus() {
|
|
4902
5193
|
try {
|
|
4903
|
-
const { stdout } = await
|
|
5194
|
+
const { stdout } = await pexec5(
|
|
4904
5195
|
"gh",
|
|
4905
5196
|
["auth", "status", "--hostname", GITHUB_HOST, "--json", "hosts"],
|
|
4906
5197
|
{
|
|
@@ -4932,7 +5223,7 @@ async function logoutGitHubCli() {
|
|
|
4932
5223
|
const status = await getGitHubCliAuthStatus();
|
|
4933
5224
|
if (!status.installed) throw new Error("\u627E\u4E0D\u5230 GitHub CLI\uFF08gh\uFF09\u3002");
|
|
4934
5225
|
if (!status.login) return status;
|
|
4935
|
-
await
|
|
5226
|
+
await pexec5(
|
|
4936
5227
|
"gh",
|
|
4937
5228
|
["auth", "logout", "--hostname", GITHUB_HOST, "--user", status.login],
|
|
4938
5229
|
{
|
|
@@ -5184,7 +5475,7 @@ function clearMessages(taskId, newSessionId) {
|
|
|
5184
5475
|
|
|
5185
5476
|
// packages/core/src/chat-session.ts
|
|
5186
5477
|
init_attachments();
|
|
5187
|
-
function
|
|
5478
|
+
function basename2(p) {
|
|
5188
5479
|
return p.split("/").pop() ?? p;
|
|
5189
5480
|
}
|
|
5190
5481
|
function truncate(s, n) {
|
|
@@ -5200,14 +5491,14 @@ function summarizeToolUse(name, input) {
|
|
|
5200
5491
|
break;
|
|
5201
5492
|
}
|
|
5202
5493
|
case "Read":
|
|
5203
|
-
summary = `Reading \`${
|
|
5494
|
+
summary = `Reading \`${basename2(String(input.file_path ?? ""))}\``;
|
|
5204
5495
|
break;
|
|
5205
5496
|
case "Write":
|
|
5206
|
-
summary = `Writing \`${
|
|
5497
|
+
summary = `Writing \`${basename2(String(input.file_path ?? ""))}\``;
|
|
5207
5498
|
break;
|
|
5208
5499
|
case "Edit":
|
|
5209
5500
|
case "MultiEdit":
|
|
5210
|
-
summary = `Editing \`${
|
|
5501
|
+
summary = `Editing \`${basename2(String(input.file_path ?? ""))}\``;
|
|
5211
5502
|
break;
|
|
5212
5503
|
case "Glob":
|
|
5213
5504
|
case "Grep":
|
|
@@ -5765,7 +6056,7 @@ function validBoard(value) {
|
|
|
5765
6056
|
}
|
|
5766
6057
|
return next;
|
|
5767
6058
|
}
|
|
5768
|
-
function createCore({ sessions, bus, version, homeDir }) {
|
|
6059
|
+
function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatus }) {
|
|
5769
6060
|
const sink = bus.sink();
|
|
5770
6061
|
let libraryCodexHome = null;
|
|
5771
6062
|
void libraryRoot().then((root) => {
|
|
@@ -5907,6 +6198,11 @@ function createCore({ sessions, bus, version, homeDir }) {
|
|
|
5907
6198
|
bus.emit("state:changed", getState());
|
|
5908
6199
|
}
|
|
5909
6200
|
let folderDialog = null;
|
|
6201
|
+
const github = createGithubService({
|
|
6202
|
+
run: ghRunner,
|
|
6203
|
+
authStatus: githubAuthStatus ?? getGitHubCliAuthStatus,
|
|
6204
|
+
repoOf: async (projectPath) => parseGithubRepo((await getGitInfo(projectPath)).remoteUrl)
|
|
6205
|
+
});
|
|
5910
6206
|
const handlers = {
|
|
5911
6207
|
"vibeflow:getState": () => getState(),
|
|
5912
6208
|
// A card's progress right now (todo list, usage, activity), for a frontend
|
|
@@ -5937,6 +6233,16 @@ function createCore({ sessions, bus, version, homeDir }) {
|
|
|
5937
6233
|
cancelGitHubCliLogin();
|
|
5938
6234
|
},
|
|
5939
6235
|
"settings:logoutGithubAuth": () => logoutGitHubCli(),
|
|
6236
|
+
// Open Issues/PRs of the board's GitHub repos that involve the signed-in
|
|
6237
|
+
// `gh` user; cached per repo, `force` refetches.
|
|
6238
|
+
"github:inbox": async (payload) => {
|
|
6239
|
+
const p = payload === void 0 ? {} : obj(payload, "payload");
|
|
6240
|
+
return github.inbox(getState().board, { force: p.force === true });
|
|
6241
|
+
},
|
|
6242
|
+
"github:taskLinks": async (payload) => {
|
|
6243
|
+
const p = payload === void 0 ? {} : obj(payload, "payload");
|
|
6244
|
+
return github.taskLinks(getState().board, { force: p.force === true });
|
|
6245
|
+
},
|
|
5940
6246
|
"env:detectAgents": () => detectAgents(),
|
|
5941
6247
|
"agents:listModels": (payload) => {
|
|
5942
6248
|
const { agentId: rawId, refresh } = obj(payload, "payload");
|
|
@@ -5966,6 +6272,7 @@ function createCore({ sessions, bus, version, homeDir }) {
|
|
|
5966
6272
|
str(p.title ?? "", "title");
|
|
5967
6273
|
if (p.effort !== void 0 && !AGENT_EFFORTS.includes(p.effort)) invalid("unknown effort");
|
|
5968
6274
|
if (p.agentCli !== void 0 && !AGENT_IDS2.includes(p.agentCli)) invalid("unknown agent");
|
|
6275
|
+
if (p.github !== void 0 && !isGithubRef(p.github)) invalid("github must be an issue or pr ref on github.com");
|
|
5969
6276
|
const { task } = await createTaskFromInput({
|
|
5970
6277
|
projectPath: p.projectPath,
|
|
5971
6278
|
title: p.title,
|
|
@@ -5977,7 +6284,8 @@ function createCore({ sessions, bus, version, homeDir }) {
|
|
|
5977
6284
|
model: p.model,
|
|
5978
6285
|
effort: p.effort,
|
|
5979
6286
|
autoMode: p.autoMode,
|
|
5980
|
-
attachments: p.attachments
|
|
6287
|
+
attachments: p.attachments,
|
|
6288
|
+
github: p.github
|
|
5981
6289
|
});
|
|
5982
6290
|
return { state: getState(), task };
|
|
5983
6291
|
},
|
|
@@ -6193,12 +6501,12 @@ function createCore({ sessions, bus, version, homeDir }) {
|
|
|
6193
6501
|
},
|
|
6194
6502
|
"task:getSpecs": async (taskId) => {
|
|
6195
6503
|
const task = requireTask(taskId);
|
|
6196
|
-
const
|
|
6197
|
-
if (task.worktreePath) return readWorktreeSpecs(task.worktreePath,
|
|
6504
|
+
const base2 = task.baseBranch ?? "main";
|
|
6505
|
+
if (task.worktreePath) return readWorktreeSpecs(task.worktreePath, base2);
|
|
6198
6506
|
const since = task.provisionedAt ?? task.launchedAt ?? (task.pushed !== void 0 ? task.createdAt : void 0);
|
|
6199
6507
|
if (!task.projectPath || !since) return [];
|
|
6200
6508
|
const changed = task.outcome?.files.filter((f) => f.status !== "D").map((f) => f.path);
|
|
6201
|
-
return readBranchSpecs(task.projectPath, task.branch,
|
|
6509
|
+
return readBranchSpecs(task.projectPath, task.branch, base2, changed, since);
|
|
6202
6510
|
},
|
|
6203
6511
|
"board:getCliLaunchInfo": () => boardCliLaunchInfo(),
|
|
6204
6512
|
"library:list": async () => listLibrary(await libraryRoot(), builtinSkillsDir()),
|
|
@@ -6466,11 +6774,11 @@ function resolveStatic(root, urlPath) {
|
|
|
6466
6774
|
}
|
|
6467
6775
|
if (decoded.includes("\0")) return null;
|
|
6468
6776
|
const rel = path22.posix.normalize(decoded).replace(/^\/+/, "");
|
|
6469
|
-
const
|
|
6777
|
+
const base2 = path22.resolve(root);
|
|
6470
6778
|
const candidates = [rel, path22.posix.join(rel, "index.html"), `${rel}.html`];
|
|
6471
6779
|
for (const c of candidates) {
|
|
6472
|
-
const full = path22.resolve(
|
|
6473
|
-
if (full !==
|
|
6780
|
+
const full = path22.resolve(base2, c);
|
|
6781
|
+
if (full !== base2 && !full.startsWith(base2 + path22.sep)) return null;
|
|
6474
6782
|
try {
|
|
6475
6783
|
if (fs18.statSync(full).isFile()) return full;
|
|
6476
6784
|
} catch {
|
|
@@ -6621,7 +6929,13 @@ Content-Length: 0\r
|
|
|
6621
6929
|
});
|
|
6622
6930
|
});
|
|
6623
6931
|
}
|
|
6624
|
-
|
|
6932
|
+
let v4;
|
|
6933
|
+
try {
|
|
6934
|
+
v4 = await listen("127.0.0.1", port);
|
|
6935
|
+
} catch (err) {
|
|
6936
|
+
if (!options.fallbackToFreePort || port === 0 || err.code !== "EADDRINUSE") throw err;
|
|
6937
|
+
v4 = await listen("127.0.0.1", 0);
|
|
6938
|
+
}
|
|
6625
6939
|
servers.push(v4);
|
|
6626
6940
|
port = v4.address().port;
|
|
6627
6941
|
try {
|
|
@@ -6639,6 +6953,7 @@ Content-Length: 0\r
|
|
|
6639
6953
|
}
|
|
6640
6954
|
|
|
6641
6955
|
// packages/cli/src/host.ts
|
|
6956
|
+
var DEFAULT_HOST_PORT = 47820;
|
|
6642
6957
|
async function waitForPort(userDataDir, timeoutMs = 1e4) {
|
|
6643
6958
|
const deadline = Date.now() + timeoutMs;
|
|
6644
6959
|
while (Date.now() < deadline) {
|
|
@@ -6697,7 +7012,8 @@ async function startHost(options) {
|
|
|
6697
7012
|
bus,
|
|
6698
7013
|
token: lock.token,
|
|
6699
7014
|
staticDir: options.staticDir,
|
|
6700
|
-
port: options.port
|
|
7015
|
+
port: options.port ?? DEFAULT_HOST_PORT,
|
|
7016
|
+
fallbackToFreePort: options.port === void 0
|
|
6701
7017
|
});
|
|
6702
7018
|
lock.port = server.port;
|
|
6703
7019
|
updateLock(options.userDataDir, lock);
|
|
@@ -6837,12 +7153,12 @@ function connectToHost(lock) {
|
|
|
6837
7153
|
// packages/cli/src/doctor.ts
|
|
6838
7154
|
import fs20 from "fs";
|
|
6839
7155
|
import path24 from "path";
|
|
6840
|
-
import { execFile as
|
|
6841
|
-
import { promisify as
|
|
7156
|
+
import { execFile as execFile9 } from "child_process";
|
|
7157
|
+
import { promisify as promisify6 } from "util";
|
|
6842
7158
|
init_env();
|
|
6843
7159
|
init_git_bash();
|
|
6844
7160
|
init_tmux_backend();
|
|
6845
|
-
var
|
|
7161
|
+
var pexec6 = promisify6(execFile9);
|
|
6846
7162
|
function parseVersion(text) {
|
|
6847
7163
|
const m = /(\d+)\.(\d+)(?:\.(\d+))?/.exec(text);
|
|
6848
7164
|
return m ? [Number(m[1]), Number(m[2]), Number(m[3] ?? 0)] : [];
|
|
@@ -6856,7 +7172,7 @@ function versionAtLeast(have, want) {
|
|
|
6856
7172
|
}
|
|
6857
7173
|
async function run2(cmd, args) {
|
|
6858
7174
|
try {
|
|
6859
|
-
const { stdout } = await
|
|
7175
|
+
const { stdout } = await pexec6(cmd, args, { env: execEnv(), timeout: 1e4, windowsHide: true });
|
|
6860
7176
|
return String(stdout).trim();
|
|
6861
7177
|
} catch {
|
|
6862
7178
|
return null;
|
|
@@ -7025,7 +7341,7 @@ Options:
|
|
|
7025
7341
|
--profile dev|prod Store profile (dev = the "(development)" store npm run dev uses)
|
|
7026
7342
|
--store-path <dir> Explicit store directory
|
|
7027
7343
|
--backend auto|tmux|pty Session backend for a new host (default: auto = tmux when installed)
|
|
7028
|
-
--port <n> Port for a new host (default:
|
|
7344
|
+
--port <n> Port for a new host (default: 47820, or a free one when taken)
|
|
7029
7345
|
--no-open Do not open a browser
|
|
7030
7346
|
--json Machine-readable output (status)
|
|
7031
7347
|
-v, --version Print the version
|