@brainervirus/workit-cli 2.0.2 → 2.1.0
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 +36 -7
- package/dist/index.js +2390 -342
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -49793,13 +49793,6 @@ var workspaceConfigSchema = object({
|
|
|
49793
49793
|
profiles: record(nonBlank, workspaceProfileSchema).optional(),
|
|
49794
49794
|
releaseTracks: record(nonBlank, releaseTrackSchema).optional()
|
|
49795
49795
|
}).passthrough().superRefine((workspace, context) => {
|
|
49796
|
-
if (workspace.youtrack && workspace.vcs?.provider !== "gitlab") {
|
|
49797
|
-
context.addIssue({
|
|
49798
|
-
code: "custom",
|
|
49799
|
-
path: ["youtrack"],
|
|
49800
|
-
message: `YouTrack issue linking requires the gitlab provider, got ${workspace.vcs?.provider ?? "unset"}`
|
|
49801
|
-
});
|
|
49802
|
-
}
|
|
49803
49796
|
if (workspace.issues && workspace.vcs?.provider !== "github") {
|
|
49804
49797
|
context.addIssue({
|
|
49805
49798
|
code: "custom",
|
|
@@ -49992,13 +49985,10 @@ var selectWorkspaceMatch = (matches, cwd, workspaceName) => {
|
|
|
49992
49985
|
}
|
|
49993
49986
|
return mostSpecific[0];
|
|
49994
49987
|
};
|
|
49995
|
-
var
|
|
49996
|
-
const result = readWorkspacesResult(dir);
|
|
49997
|
-
if (result.status === "malformed" || result.status === "invalid")
|
|
49998
|
-
throw new Error(result.error);
|
|
49988
|
+
var resolveWorkspaceFromEntries = (cwd, entries, workspaceName) => {
|
|
49999
49989
|
const targets = [cwd, realpathOf(cwd)].map((p) => p.replaceAll("\\", "/"));
|
|
50000
49990
|
const matches = [];
|
|
50001
|
-
for (const ws of
|
|
49991
|
+
for (const ws of entries) {
|
|
50002
49992
|
const glob = ws.glob.replaceAll("\\", "/");
|
|
50003
49993
|
const canonical = canonicalGlob(glob);
|
|
50004
49994
|
let matched = false;
|
|
@@ -50013,6 +50003,12 @@ var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
|
|
|
50013
50003
|
}
|
|
50014
50004
|
return selectWorkspaceMatch(matches, cwd, workspaceName) ?? null;
|
|
50015
50005
|
};
|
|
50006
|
+
var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
|
|
50007
|
+
const result = readWorkspacesResult(dir);
|
|
50008
|
+
if (result.status === "malformed" || result.status === "invalid")
|
|
50009
|
+
throw new Error(result.error);
|
|
50010
|
+
return resolveWorkspaceFromEntries(cwd, result.entries, workspaceName);
|
|
50011
|
+
};
|
|
50016
50012
|
var runtimeWorkspacePolicySchema = (kind) => {
|
|
50017
50013
|
const key = kind === "branch" ? "branchPolicy" : kind === "commit" ? "commitPolicy" : "vcs";
|
|
50018
50014
|
const policySchema = kind === "branch" ? workspaceBranchPolicySchema : kind === "commit" ? workspaceCommitPolicySchema : object({
|
|
@@ -50096,6 +50092,48 @@ var resolveRuntimeWorkspacePolicy = (cwd, kind, requestedProfile) => {
|
|
|
50096
50092
|
source: profilePolicy ? `profile:${profileName}` : workspacePolicy ? `workspace:${candidate.name}` : "user-default"
|
|
50097
50093
|
};
|
|
50098
50094
|
};
|
|
50095
|
+
var resolveWorkspaceProfile = (workspace, requestedProfile) => {
|
|
50096
|
+
const profileName = requestedProfile ?? workspace.defaultProfile ?? null;
|
|
50097
|
+
const profile = profileName ? workspace.profiles?.[profileName] : undefined;
|
|
50098
|
+
if (profileName && !profile) {
|
|
50099
|
+
return {
|
|
50100
|
+
status: "invalid",
|
|
50101
|
+
error: `workspace ${JSON.stringify(workspace.name)} has no profile ${JSON.stringify(profileName)}`
|
|
50102
|
+
};
|
|
50103
|
+
}
|
|
50104
|
+
const effectiveWorkspace = profile ? {
|
|
50105
|
+
...workspace,
|
|
50106
|
+
...profile.branchPolicy ? { branchPolicy: profile.branchPolicy } : {},
|
|
50107
|
+
...profile.commitPolicy ? { commitPolicy: profile.commitPolicy } : {}
|
|
50108
|
+
} : workspace;
|
|
50109
|
+
return {
|
|
50110
|
+
status: "resolved",
|
|
50111
|
+
profileName,
|
|
50112
|
+
workspace: effectiveWorkspace,
|
|
50113
|
+
provenance: {
|
|
50114
|
+
branchPolicy: profile?.branchPolicy ? `profile:${profileName}` : workspace.branchPolicy ? `workspace:${workspace.name}` : "user-default",
|
|
50115
|
+
commitPolicy: profile?.commitPolicy ? `profile:${profileName}` : workspace.commitPolicy ? `workspace:${workspace.name}` : "user-default"
|
|
50116
|
+
}
|
|
50117
|
+
};
|
|
50118
|
+
};
|
|
50119
|
+
var resolveWorkspacePolicy = (config, workspace, profileName) => {
|
|
50120
|
+
const selected = workspace ? resolveWorkspaceProfile(workspace, profileName) : {
|
|
50121
|
+
status: "resolved",
|
|
50122
|
+
profileName: null,
|
|
50123
|
+
workspace: null,
|
|
50124
|
+
provenance: { branchPolicy: "user-default", commitPolicy: "user-default" }
|
|
50125
|
+
};
|
|
50126
|
+
if (selected.status === "invalid")
|
|
50127
|
+
return selected;
|
|
50128
|
+
return {
|
|
50129
|
+
status: "resolved",
|
|
50130
|
+
workspace: selected.workspace,
|
|
50131
|
+
profileName: selected.profileName,
|
|
50132
|
+
branchPolicy: resolveBranchPolicy(config, selected.workspace),
|
|
50133
|
+
commitPolicy: resolveCommitPolicy(config, selected.workspace),
|
|
50134
|
+
provenance: selected.provenance
|
|
50135
|
+
};
|
|
50136
|
+
};
|
|
50099
50137
|
|
|
50100
50138
|
// packages/workit-core/src/core/gitignore.ts
|
|
50101
50139
|
var GITIGNORE_ENTRIES = [
|
|
@@ -50607,20 +50645,20 @@ function writeFileAtomic(file, content, mode) {
|
|
|
50607
50645
|
import {
|
|
50608
50646
|
copyFileSync as copyFileSync2,
|
|
50609
50647
|
cpSync as cpSync3,
|
|
50610
|
-
existsSync as
|
|
50648
|
+
existsSync as existsSync11,
|
|
50611
50649
|
lstatSync as lstatSync4,
|
|
50612
50650
|
mkdirSync as mkdirSync5,
|
|
50613
50651
|
mkdtempSync,
|
|
50614
|
-
readFileSync as
|
|
50615
|
-
readdirSync as
|
|
50652
|
+
readFileSync as readFileSync12,
|
|
50653
|
+
readdirSync as readdirSync5,
|
|
50616
50654
|
realpathSync as realpathSync2,
|
|
50617
50655
|
renameSync as renameSync2,
|
|
50618
50656
|
rmSync,
|
|
50619
|
-
statSync as
|
|
50657
|
+
statSync as statSync4,
|
|
50620
50658
|
writeFileSync as writeFileSync5
|
|
50621
50659
|
} from "node:fs";
|
|
50622
|
-
import
|
|
50623
|
-
import
|
|
50660
|
+
import os7 from "node:os";
|
|
50661
|
+
import path14 from "node:path";
|
|
50624
50662
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
|
|
50625
50663
|
|
|
50626
50664
|
// packages/workit-core/src/core/branch-policy.ts
|
|
@@ -50729,7 +50767,7 @@ var named = (s, name) => s === name || s.startsWith(`${name}@`);
|
|
|
50729
50767
|
function isWorkitPlugin(value) {
|
|
50730
50768
|
const s = String(value).replaceAll("\\", "/");
|
|
50731
50769
|
const url = s.startsWith("file://") || s.startsWith("git+file://");
|
|
50732
|
-
const pkgPath =
|
|
50770
|
+
const pkgPath = /\/(?:packages\/workit-(?:opencode|cursor)|node_modules\/@brainervirus\/workit-(?:opencode|cursor))(?:\/|$)/.test(s);
|
|
50733
50771
|
return named(s, "workflow-toolkit") || named(s, "workflow-toolkit-opencode") || named(s, "local/workflow-toolkit") || named(s, "workit") || named(s, "local/workit") || named(s, "@brainervirus/workit-opencode") || named(s, "@brainervirus/workit-cursor") || url && pkgPath || s.startsWith("git+file://") && s.includes("workflow-toolkit");
|
|
50734
50772
|
}
|
|
50735
50773
|
function mergeOpenCodePlugins(plugin, pin) {
|
|
@@ -53344,9 +53382,10 @@ var parsesAsConfigObject = (p) => {
|
|
|
53344
53382
|
}
|
|
53345
53383
|
};
|
|
53346
53384
|
var pluginEntries = (cfg) => {
|
|
53347
|
-
const
|
|
53348
|
-
|
|
53349
|
-
|
|
53385
|
+
const entries = [cfg?.plugins, cfg?.plugin].flatMap((value) => Array.isArray(value) ? value : typeof value === "string" ? [value] : []);
|
|
53386
|
+
return [
|
|
53387
|
+
...new Set(entries.filter((entry) => typeof entry === "string" && isWorkitPlugin(entry)))
|
|
53388
|
+
];
|
|
53350
53389
|
};
|
|
53351
53390
|
var commandOnPath = (name, env) => {
|
|
53352
53391
|
const dirs = (env.PATH ?? process.env.PATH ?? "").split(path12.delimiter);
|
|
@@ -54603,6 +54642,351 @@ var runDoctor = (options = {}) => {
|
|
|
54603
54642
|
return report;
|
|
54604
54643
|
};
|
|
54605
54644
|
|
|
54645
|
+
// packages/workit-core/src/core/host-install.ts
|
|
54646
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
54647
|
+
import { accessSync, constants as constants2, existsSync as existsSync10, readFileSync as readFileSync11, readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
|
|
54648
|
+
import os6 from "node:os";
|
|
54649
|
+
import path13 from "node:path";
|
|
54650
|
+
function hostCommand(name, args, options = {}) {
|
|
54651
|
+
const executable = findHostExecutable(name, options);
|
|
54652
|
+
if (!executable)
|
|
54653
|
+
throw new Error(`${name} executable was not found on PATH or supported user bin directories`);
|
|
54654
|
+
if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(executable)) {
|
|
54655
|
+
const node = findHostExecutable("node", options);
|
|
54656
|
+
if (!node)
|
|
54657
|
+
throw new Error(`Node.js is required to run the ${name} Windows shim`);
|
|
54658
|
+
const script = resolveWindowsShimScript(executable);
|
|
54659
|
+
if (!script)
|
|
54660
|
+
throw new Error(`could not resolve the ${name} Windows shim to a JavaScript entrypoint`);
|
|
54661
|
+
return { command: node, args: [script, ...args], cwd: options.cwd, purpose: `${name} CLI` };
|
|
54662
|
+
}
|
|
54663
|
+
return { command: executable, args, cwd: options.cwd, purpose: `${name} CLI` };
|
|
54664
|
+
}
|
|
54665
|
+
function resolveWindowsShimEntry(contents, shim, exists = existsSync10) {
|
|
54666
|
+
const root = path13.win32.dirname(shim);
|
|
54667
|
+
const matches = contents.matchAll(/(["']?)([^\r\n"']*node_modules[\\/][^\r\n"']+?\.js)\1/gi);
|
|
54668
|
+
for (const match of matches) {
|
|
54669
|
+
const raw = match[2].replace(/%~?dp0%?/gi, root);
|
|
54670
|
+
const candidate = path13.win32.isAbsolute(raw) ? raw : path13.win32.resolve(root, raw);
|
|
54671
|
+
if (exists(candidate))
|
|
54672
|
+
return candidate;
|
|
54673
|
+
}
|
|
54674
|
+
return null;
|
|
54675
|
+
}
|
|
54676
|
+
var resolveWindowsShimScript = (shim) => {
|
|
54677
|
+
try {
|
|
54678
|
+
const contents = readFileSync11(shim, "utf8");
|
|
54679
|
+
return resolveWindowsShimEntry(contents, shim);
|
|
54680
|
+
} catch {
|
|
54681
|
+
return null;
|
|
54682
|
+
}
|
|
54683
|
+
};
|
|
54684
|
+
var MARKETPLACE = "https://github.com/BrainerVirus/workit.git";
|
|
54685
|
+
var CODEX_MARKETPLACE_NAME = "workflow-toolkit";
|
|
54686
|
+
var validPackageVersion = (value) => value === "latest" || /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(value);
|
|
54687
|
+
var nodePrerequisite = (options) => {
|
|
54688
|
+
const node = findHostExecutable("node", options);
|
|
54689
|
+
if (!node)
|
|
54690
|
+
throw new Error("Workit host packages require Node.js 24+; install Node.js and retry");
|
|
54691
|
+
return {
|
|
54692
|
+
command: node,
|
|
54693
|
+
args: [
|
|
54694
|
+
"-e",
|
|
54695
|
+
'const v=Number(process.versions.node.split(".")[0]);if(v<24){console.error(`Workit host packages require Node.js 24+ (found ${process.versions.node})`);process.exit(1)}'
|
|
54696
|
+
],
|
|
54697
|
+
cwd: options.cwd,
|
|
54698
|
+
purpose: "Check the Node.js 24+ package runtime requirement"
|
|
54699
|
+
};
|
|
54700
|
+
};
|
|
54701
|
+
function findHostExecutable(name, options = {}) {
|
|
54702
|
+
const env = options.env ?? process.env;
|
|
54703
|
+
const home = options.home ?? env.HOME ?? os6.homedir();
|
|
54704
|
+
const suffixes = process.platform === "win32" ? ["", ".exe", ".cmd", ".bat"] : [""];
|
|
54705
|
+
const dirs = (env.PATH ?? "").split(path13.delimiter).filter(Boolean);
|
|
54706
|
+
dirs.push(path13.join(home, ".local", "bin"), path13.join(home, ".asdf", "shims"));
|
|
54707
|
+
for (const [base, tail] of [
|
|
54708
|
+
[path13.join(home, ".local", "share", "fnm", "node-versions"), path13.join("installation", "bin")],
|
|
54709
|
+
[path13.join(home, ".nvm", "versions", "node"), "bin"]
|
|
54710
|
+
]) {
|
|
54711
|
+
try {
|
|
54712
|
+
for (const entry of readdirSync4(base, { withFileTypes: true })) {
|
|
54713
|
+
if (entry.isDirectory())
|
|
54714
|
+
dirs.push(path13.join(base, entry.name, tail));
|
|
54715
|
+
}
|
|
54716
|
+
} catch {}
|
|
54717
|
+
}
|
|
54718
|
+
for (const dir of dirs) {
|
|
54719
|
+
for (const suffix of suffixes) {
|
|
54720
|
+
const candidate = path13.join(dir, `${name}${suffix}`);
|
|
54721
|
+
try {
|
|
54722
|
+
if (statSync3(candidate).isFile()) {
|
|
54723
|
+
if (process.platform === "win32")
|
|
54724
|
+
return candidate;
|
|
54725
|
+
accessSync(candidate, constants2.X_OK);
|
|
54726
|
+
return candidate;
|
|
54727
|
+
}
|
|
54728
|
+
} catch {}
|
|
54729
|
+
}
|
|
54730
|
+
}
|
|
54731
|
+
return null;
|
|
54732
|
+
}
|
|
54733
|
+
var isPiWorkitInstalled = (home, env = process.env) => {
|
|
54734
|
+
const settings = path13.join(env.PI_CODING_AGENT_DIR ?? path13.join(home, ".pi", "agent"), "settings.json");
|
|
54735
|
+
try {
|
|
54736
|
+
const document2 = JSON.parse(readFileSync11(settings, "utf8"));
|
|
54737
|
+
return (document2.packages ?? []).some((entry) => {
|
|
54738
|
+
const source = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.source : entry;
|
|
54739
|
+
const value = String(source).replaceAll("\\", "/").replace(/\/+$/, "");
|
|
54740
|
+
return /^npm:@brainervirus\/workit-pi(?:@[^/]+)?$/.test(value) || value === "@brainervirus/workit-pi" || /(?:^|\/)packages\/workit-pi$/.test(value);
|
|
54741
|
+
});
|
|
54742
|
+
} catch {
|
|
54743
|
+
return false;
|
|
54744
|
+
}
|
|
54745
|
+
};
|
|
54746
|
+
var isCanonicalCodexPackage = (root) => {
|
|
54747
|
+
for (const file of [
|
|
54748
|
+
path13.join(root, ".codex-plugin", "plugin.json"),
|
|
54749
|
+
path13.join(root, "package.json")
|
|
54750
|
+
]) {
|
|
54751
|
+
try {
|
|
54752
|
+
const manifest = JSON.parse(readFileSync11(file, "utf8"));
|
|
54753
|
+
const repository = typeof manifest.repository === "string" ? manifest.repository : manifest.repository?.url;
|
|
54754
|
+
if ((manifest.name === "workit" || manifest.name === "@brainervirus/workit-codex") && repository?.replace(/\.git$/, "").toLowerCase() === "https://github.com/brainervirus/workit")
|
|
54755
|
+
return true;
|
|
54756
|
+
} catch {}
|
|
54757
|
+
}
|
|
54758
|
+
return false;
|
|
54759
|
+
};
|
|
54760
|
+
var isCodexWorkitInstalled = (home, env = process.env) => {
|
|
54761
|
+
const codexHome = env.CODEX_HOME ?? path13.join(home, ".codex");
|
|
54762
|
+
const isPackageOrVersionDirectory = (root) => {
|
|
54763
|
+
if (isCanonicalCodexPackage(root))
|
|
54764
|
+
return true;
|
|
54765
|
+
try {
|
|
54766
|
+
return readdirSync4(root, { withFileTypes: true }).some((entry) => entry.isDirectory() && isCanonicalCodexPackage(path13.join(root, entry.name)));
|
|
54767
|
+
} catch {
|
|
54768
|
+
return false;
|
|
54769
|
+
}
|
|
54770
|
+
};
|
|
54771
|
+
if (isPackageOrVersionDirectory(path13.join(codexHome, "plugins", "workit")))
|
|
54772
|
+
return true;
|
|
54773
|
+
const root = path13.join(codexHome, "plugins", "cache");
|
|
54774
|
+
try {
|
|
54775
|
+
for (const marketplace of readdirSync4(root, { withFileTypes: true })) {
|
|
54776
|
+
if (!marketplace.isDirectory())
|
|
54777
|
+
continue;
|
|
54778
|
+
if (isPackageOrVersionDirectory(path13.join(root, marketplace.name, "workit")))
|
|
54779
|
+
return true;
|
|
54780
|
+
}
|
|
54781
|
+
} catch {
|
|
54782
|
+
return false;
|
|
54783
|
+
}
|
|
54784
|
+
return false;
|
|
54785
|
+
};
|
|
54786
|
+
function installedHostApp(host, home, env = process.env, platform = process.platform, exists = existsSync10) {
|
|
54787
|
+
const candidates = [];
|
|
54788
|
+
const pathApi = platform === "win32" ? path13.win32 : path13;
|
|
54789
|
+
if (platform === "darwin") {
|
|
54790
|
+
const app = host === "cursor" ? "Cursor.app" : host === "codex" ? "Codex.app" : host === "opencode" ? "OpenCode.app" : "";
|
|
54791
|
+
if (app)
|
|
54792
|
+
candidates.push(`/Applications/${app}`, pathApi.join(home, "Applications", app));
|
|
54793
|
+
} else if (platform === "win32") {
|
|
54794
|
+
const local = env.LOCALAPPDATA ?? pathApi.join(home, "AppData", "Local");
|
|
54795
|
+
if (host === "cursor")
|
|
54796
|
+
candidates.push(pathApi.join(local, "Programs", "Cursor", "Cursor.exe"));
|
|
54797
|
+
if (host === "codex")
|
|
54798
|
+
candidates.push(pathApi.join(local, "Programs", "Codex", "Codex.exe"));
|
|
54799
|
+
if (host === "opencode")
|
|
54800
|
+
candidates.push(pathApi.join(local, "Programs", "OpenCode", "OpenCode.exe"));
|
|
54801
|
+
}
|
|
54802
|
+
return candidates.some(exists);
|
|
54803
|
+
}
|
|
54804
|
+
function planHostInstall(host, options = {}) {
|
|
54805
|
+
const env = options.env ?? process.env;
|
|
54806
|
+
const home = options.home ?? env.HOME ?? os6.homedir();
|
|
54807
|
+
const cwd = options.cwd ?? process.cwd();
|
|
54808
|
+
const version = options.packageVersion ?? "latest";
|
|
54809
|
+
if (!validPackageVersion(version))
|
|
54810
|
+
throw new Error(`unsupported package version selector: ${version}`);
|
|
54811
|
+
if (options.alreadyInstalled && options.mode !== "upgrade")
|
|
54812
|
+
return [];
|
|
54813
|
+
const upgrading = options.mode === "upgrade";
|
|
54814
|
+
if (host === "codex") {
|
|
54815
|
+
if (!upgrading && isCodexWorkitInstalled(home, env))
|
|
54816
|
+
return [];
|
|
54817
|
+
const base = hostCommand("codex", [], { home, cwd, env });
|
|
54818
|
+
return [
|
|
54819
|
+
nodePrerequisite({ home, cwd, env }),
|
|
54820
|
+
{
|
|
54821
|
+
...base,
|
|
54822
|
+
args: [...base.args, "plugin", "marketplace", "list"],
|
|
54823
|
+
purpose: "Check whether the Workit marketplace is already registered"
|
|
54824
|
+
},
|
|
54825
|
+
{
|
|
54826
|
+
...base,
|
|
54827
|
+
args: [
|
|
54828
|
+
...base.args,
|
|
54829
|
+
"plugin",
|
|
54830
|
+
"marketplace",
|
|
54831
|
+
upgrading ? "upgrade" : "add",
|
|
54832
|
+
...upgrading ? [CODEX_MARKETPLACE_NAME] : [MARKETPLACE]
|
|
54833
|
+
],
|
|
54834
|
+
purpose: upgrading ? "Refresh the Workit Codex marketplace" : "Register the Workit Codex marketplace",
|
|
54835
|
+
...upgrading ? {} : { skipWhenOutputIncludes: CODEX_MARKETPLACE_NAME }
|
|
54836
|
+
},
|
|
54837
|
+
{
|
|
54838
|
+
...base,
|
|
54839
|
+
args: [...base.args, "plugin", "add", `workit@${CODEX_MARKETPLACE_NAME}`],
|
|
54840
|
+
purpose: upgrading ? "Refresh the Workit Codex plugin" : "Install the Workit Codex plugin"
|
|
54841
|
+
}
|
|
54842
|
+
];
|
|
54843
|
+
}
|
|
54844
|
+
if (host === "pi") {
|
|
54845
|
+
if (!upgrading && isPiWorkitInstalled(home, env))
|
|
54846
|
+
return [];
|
|
54847
|
+
const base = hostCommand("pi", [], { home, cwd, env });
|
|
54848
|
+
return [
|
|
54849
|
+
nodePrerequisite({ home, cwd, env }),
|
|
54850
|
+
{
|
|
54851
|
+
...base,
|
|
54852
|
+
args: upgrading ? [...base.args, "update", "--extension", "npm:@brainervirus/workit-pi"] : [...base.args, "install", `npm:@brainervirus/workit-pi@${version}`],
|
|
54853
|
+
purpose: upgrading ? "Update the Workit Pi package" : "Install the Workit Pi package in personal Pi settings"
|
|
54854
|
+
}
|
|
54855
|
+
];
|
|
54856
|
+
}
|
|
54857
|
+
if (host === "cursor") {
|
|
54858
|
+
const node = findHostExecutable("node", { home, env });
|
|
54859
|
+
if (!node)
|
|
54860
|
+
throw new Error("Workit host packages require Node.js 24+; install Node.js and retry");
|
|
54861
|
+
const npm = findHostExecutable("npm", { home, env });
|
|
54862
|
+
const npmCli = npm ? findNpmCli(npm) : null;
|
|
54863
|
+
if (!npmCli)
|
|
54864
|
+
throw new Error("npm CLI could not be resolved; install Node.js 24+ and npm, then retry");
|
|
54865
|
+
const stage = path13.join(home, ".cursor", "plugins", "local", ".workit-package-bootstrap");
|
|
54866
|
+
const target = options.targetDir ?? path13.join(home, ".cursor", "plugins", "local", "workit");
|
|
54867
|
+
return [
|
|
54868
|
+
nodePrerequisite({ home, cwd, env }),
|
|
54869
|
+
{
|
|
54870
|
+
command: node,
|
|
54871
|
+
args: [
|
|
54872
|
+
npmCli,
|
|
54873
|
+
"install",
|
|
54874
|
+
"--prefix",
|
|
54875
|
+
stage,
|
|
54876
|
+
"--no-save",
|
|
54877
|
+
"--package-lock=false",
|
|
54878
|
+
`@brainervirus/workit-cursor@${version}`
|
|
54879
|
+
],
|
|
54880
|
+
cwd,
|
|
54881
|
+
purpose: upgrading ? "Download the current Workit Cursor adapter for the managed local plugin directory" : "Download the Workit Cursor adapter package for the managed local plugin directory",
|
|
54882
|
+
packageRoot: path13.join(stage, "node_modules", "@brainervirus", "workit-cursor"),
|
|
54883
|
+
packageTarget: target
|
|
54884
|
+
}
|
|
54885
|
+
];
|
|
54886
|
+
}
|
|
54887
|
+
if (host === "opencode") {
|
|
54888
|
+
if (upgrading)
|
|
54889
|
+
throw new Error("OpenCode CLI cannot target the Workit server plugin for a scoped update; upgrade is unsupported and the current registration was preserved");
|
|
54890
|
+
return [];
|
|
54891
|
+
}
|
|
54892
|
+
return [];
|
|
54893
|
+
}
|
|
54894
|
+
function runHostInstall(commands, runner, context = {}) {
|
|
54895
|
+
const results = [];
|
|
54896
|
+
let packageRoot;
|
|
54897
|
+
let outputHistory = "";
|
|
54898
|
+
for (const command of commands) {
|
|
54899
|
+
if (command.skipWhenOutputIncludes && outputHistory.includes(command.skipWhenOutputIncludes)) {
|
|
54900
|
+
results.push({
|
|
54901
|
+
command,
|
|
54902
|
+
result: { exitCode: 0, stdout: "", stderr: "already registered; skipped" }
|
|
54903
|
+
});
|
|
54904
|
+
continue;
|
|
54905
|
+
}
|
|
54906
|
+
const result = runner ? runner(command) : runHostCommand(command, context);
|
|
54907
|
+
results.push({ command, result });
|
|
54908
|
+
if (result.exitCode !== 0)
|
|
54909
|
+
return { ok: false, results };
|
|
54910
|
+
outputHistory += `
|
|
54911
|
+
${result.stdout}
|
|
54912
|
+
${result.stderr}`;
|
|
54913
|
+
if (command.packageRoot && command.packageTarget) {
|
|
54914
|
+
try {
|
|
54915
|
+
if (!existsSync10(command.packageRoot)) {
|
|
54916
|
+
return {
|
|
54917
|
+
ok: false,
|
|
54918
|
+
results: [
|
|
54919
|
+
{
|
|
54920
|
+
command,
|
|
54921
|
+
result: {
|
|
54922
|
+
...result,
|
|
54923
|
+
exitCode: 1,
|
|
54924
|
+
stderr: "npm completed without producing the expected Cursor package"
|
|
54925
|
+
}
|
|
54926
|
+
}
|
|
54927
|
+
]
|
|
54928
|
+
};
|
|
54929
|
+
} else {
|
|
54930
|
+
packageRoot = command.packageRoot;
|
|
54931
|
+
}
|
|
54932
|
+
} catch (error) {
|
|
54933
|
+
return {
|
|
54934
|
+
ok: false,
|
|
54935
|
+
results: [
|
|
54936
|
+
{
|
|
54937
|
+
command,
|
|
54938
|
+
result: {
|
|
54939
|
+
...result,
|
|
54940
|
+
exitCode: 1,
|
|
54941
|
+
stderr: error instanceof Error ? error.message : String(error)
|
|
54942
|
+
}
|
|
54943
|
+
}
|
|
54944
|
+
]
|
|
54945
|
+
};
|
|
54946
|
+
}
|
|
54947
|
+
}
|
|
54948
|
+
}
|
|
54949
|
+
return { ok: true, results, packageRoot };
|
|
54950
|
+
}
|
|
54951
|
+
function runHostCommand(step, context = {}) {
|
|
54952
|
+
if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(step.command)) {
|
|
54953
|
+
return {
|
|
54954
|
+
exitCode: 1,
|
|
54955
|
+
stdout: "",
|
|
54956
|
+
stderr: `Cannot safely execute batch shim ${step.command}; resolve its Node.js CLI entrypoint and retry`
|
|
54957
|
+
};
|
|
54958
|
+
}
|
|
54959
|
+
const result = spawnSync3(step.command, step.args, {
|
|
54960
|
+
cwd: step.cwd,
|
|
54961
|
+
env: (() => {
|
|
54962
|
+
const home = context.home ?? context.env?.HOME ?? os6.homedir();
|
|
54963
|
+
const env = { ...process.env, ...context.env, HOME: home };
|
|
54964
|
+
env.CODEX_HOME = context.env?.CODEX_HOME ?? path13.join(home, ".codex");
|
|
54965
|
+
env.PI_CODING_AGENT_DIR = context.env?.PI_CODING_AGENT_DIR ?? path13.join(home, ".pi", "agent");
|
|
54966
|
+
env.XDG_CONFIG_HOME = context.env?.XDG_CONFIG_HOME ?? path13.join(home, ".config");
|
|
54967
|
+
return env;
|
|
54968
|
+
})(),
|
|
54969
|
+
encoding: "utf8",
|
|
54970
|
+
timeout: 60000,
|
|
54971
|
+
windowsHide: true,
|
|
54972
|
+
shell: false
|
|
54973
|
+
});
|
|
54974
|
+
return {
|
|
54975
|
+
exitCode: result.status ?? (result.error ? 1 : 1),
|
|
54976
|
+
stdout: result.stdout ?? "",
|
|
54977
|
+
stderr: result.stderr ?? result.error?.message ?? ""
|
|
54978
|
+
};
|
|
54979
|
+
}
|
|
54980
|
+
var findNpmCli = (npm) => {
|
|
54981
|
+
const dir = path13.dirname(npm);
|
|
54982
|
+
const candidates = [
|
|
54983
|
+
path13.join(dir, "node_modules", "npm", "bin", "npm-cli.js"),
|
|
54984
|
+
path13.join(dir, "..", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
54985
|
+
path13.join(dir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
54986
|
+
];
|
|
54987
|
+
return candidates.find((candidate) => existsSync10(candidate)) ?? null;
|
|
54988
|
+
};
|
|
54989
|
+
|
|
54606
54990
|
// packages/workit-core/src/core/setup.ts
|
|
54607
54991
|
var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE";
|
|
54608
54992
|
function parseList(raw) {
|
|
@@ -54682,7 +55066,7 @@ var resolveTokenPath = (configured, fallback, override) => {
|
|
|
54682
55066
|
};
|
|
54683
55067
|
var readConfigRecord = (file) => {
|
|
54684
55068
|
try {
|
|
54685
|
-
const value = JSON.parse(
|
|
55069
|
+
const value = JSON.parse(readFileSync12(file, "utf8"));
|
|
54686
55070
|
return isRecord2(value) ? value : null;
|
|
54687
55071
|
} catch {
|
|
54688
55072
|
return null;
|
|
@@ -54703,11 +55087,12 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
54703
55087
|
const current = readConfigFromDir(state.configDir);
|
|
54704
55088
|
mutations.push({
|
|
54705
55089
|
type: "merge-json",
|
|
54706
|
-
path:
|
|
55090
|
+
path: path14.join(state.configDir, "config.json"),
|
|
54707
55091
|
value: {
|
|
54708
55092
|
locale: values.locale,
|
|
54709
55093
|
localeOptions: current.localeOptions,
|
|
54710
55094
|
timezone: values.timezone,
|
|
55095
|
+
...values.commitPolicy === undefined ? {} : { commitPolicy: values.commitPolicy },
|
|
54711
55096
|
branchPolicy: mergePreset(values.branchPreset, {
|
|
54712
55097
|
allowed: values.branchPreset === "custom" ? parseList(values.branchAllowed) : undefined,
|
|
54713
55098
|
protectedNames: values.branchPreset === "custom" ? parseList(values.branchProtected) : undefined
|
|
@@ -54729,17 +55114,17 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
54729
55114
|
if (blocked.length === 0) {
|
|
54730
55115
|
mutations.push({
|
|
54731
55116
|
type: "update-workspaces",
|
|
54732
|
-
path:
|
|
55117
|
+
path: path14.join(state.configDir, "workspaces.json"),
|
|
54733
55118
|
entries: values.workspaces,
|
|
54734
55119
|
expectedRevision: diskWorkspaceResult.revision
|
|
54735
55120
|
});
|
|
54736
55121
|
}
|
|
54737
55122
|
}
|
|
54738
55123
|
if (values.baseUrl.trim()) {
|
|
54739
|
-
const ytPath =
|
|
55124
|
+
const ytPath = path14.join(state.configDir, "youtrack.json");
|
|
54740
55125
|
const ytExisting = readConfigRecord(ytPath);
|
|
54741
55126
|
const ytConfigured = configuredTokenPath(ytExisting, "tokenFile");
|
|
54742
|
-
const tokenPath = resolveTokenPath(ytConfigured,
|
|
55127
|
+
const tokenPath = resolveTokenPath(ytConfigured, path14.join(state.configDir, "youtrack.token"), values.tokenPaths?.youtrack);
|
|
54743
55128
|
const draft = youtrackDraft(values, tokenPath);
|
|
54744
55129
|
if (ytConfigured !== null && tokenPath !== ytConfigured) {
|
|
54745
55130
|
delete draft.tokenFile;
|
|
@@ -54755,7 +55140,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
54755
55140
|
path: ytPath,
|
|
54756
55141
|
value: draft
|
|
54757
55142
|
});
|
|
54758
|
-
if (
|
|
55143
|
+
if (existsSync11(tokenPath))
|
|
54759
55144
|
preserved.push(tokenPath);
|
|
54760
55145
|
else
|
|
54761
55146
|
mutations.push({
|
|
@@ -54767,7 +55152,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
54767
55152
|
});
|
|
54768
55153
|
}
|
|
54769
55154
|
if (values.vcsProvider !== "skip") {
|
|
54770
|
-
const vcsPath =
|
|
55155
|
+
const vcsPath = path14.join(state.configDir, "vcs.json");
|
|
54771
55156
|
mutations.push({
|
|
54772
55157
|
type: "merge-json",
|
|
54773
55158
|
path: vcsPath,
|
|
@@ -54781,16 +55166,45 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
54781
55166
|
if (platform === "opencode") {
|
|
54782
55167
|
mutations.push({ type: "register-platform", platform, path: paths.opencodeConfig });
|
|
54783
55168
|
} else if (platform === "cursor") {
|
|
55169
|
+
const cursorRoot = adapterRoot("cursor", {
|
|
55170
|
+
...paths,
|
|
55171
|
+
dev: opts.dev ?? env.WORKFLOW_TOOLKIT_DEV ?? null
|
|
55172
|
+
});
|
|
55173
|
+
if (cursorRoot === null) {
|
|
55174
|
+
const commands = planHostInstall("cursor", {
|
|
55175
|
+
home: paths.home,
|
|
55176
|
+
cwd: paths.cwd,
|
|
55177
|
+
env,
|
|
55178
|
+
packageVersion: "latest",
|
|
55179
|
+
targetDir: paths.cursorPluginDir
|
|
55180
|
+
});
|
|
55181
|
+
mutations.push({
|
|
55182
|
+
type: "install-host",
|
|
55183
|
+
platform: "cursor",
|
|
55184
|
+
path: path14.join(paths.home, ".cursor", "plugins", "local", ".workit-package-bootstrap"),
|
|
55185
|
+
commands
|
|
55186
|
+
});
|
|
55187
|
+
}
|
|
54784
55188
|
mutations.push({ type: "install-adapter", platform, path: paths.cursorPluginDir });
|
|
54785
55189
|
mutations.push({ type: "register-platform", platform, path: paths.cursorSettings });
|
|
54786
55190
|
mutations.push({ type: "register-platform", platform, path: paths.cursorMcp });
|
|
55191
|
+
} else if (platform === "codex" || platform === "pi") {
|
|
55192
|
+
const commands = planHostInstall(platform, { home: paths.home, cwd: paths.cwd, env });
|
|
55193
|
+
if (commands.length > 0) {
|
|
55194
|
+
mutations.push({
|
|
55195
|
+
type: "install-host",
|
|
55196
|
+
platform,
|
|
55197
|
+
path: platform === "codex" ? path14.join(env.CODEX_HOME ?? path14.join(paths.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : path14.join(env.PI_CODING_AGENT_DIR ?? path14.join(paths.home, ".pi", "agent"), "settings.json"),
|
|
55198
|
+
commands
|
|
55199
|
+
});
|
|
55200
|
+
}
|
|
54787
55201
|
}
|
|
54788
55202
|
}
|
|
54789
55203
|
}
|
|
54790
55204
|
if (values.applyProject) {
|
|
54791
|
-
const root =
|
|
54792
|
-
const gitignorePath =
|
|
54793
|
-
const existing =
|
|
55205
|
+
const root = path14.resolve(opts.cwd ?? process.cwd());
|
|
55206
|
+
const gitignorePath = path14.join(root, ".gitignore");
|
|
55207
|
+
const existing = existsSync11(gitignorePath) ? readFileSync12(gitignorePath, "utf8") : "";
|
|
54794
55208
|
const existingLines = new Set(existing.split(`
|
|
54795
55209
|
`).map((l) => l.trim()).filter(Boolean));
|
|
54796
55210
|
const entries = GITIGNORE_ENTRIES.filter((e) => e.trim() !== "" && !existingLines.has(e.trim()));
|
|
@@ -54812,16 +55226,16 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
54812
55226
|
}
|
|
54813
55227
|
var resolveSetupPaths = (options, configDir) => {
|
|
54814
55228
|
const env = options.env ?? process.env;
|
|
54815
|
-
const home = options.home ?? env.HOME ??
|
|
55229
|
+
const home = options.home ?? env.HOME ?? os7.homedir();
|
|
54816
55230
|
return {
|
|
54817
55231
|
home,
|
|
54818
55232
|
configDir,
|
|
54819
55233
|
cwd: options.cwd ?? process.cwd(),
|
|
54820
55234
|
env,
|
|
54821
|
-
opencodeConfig: options.opencodeConfig ??
|
|
54822
|
-
cursorSettings: options.cursorSettings ??
|
|
54823
|
-
cursorMcp: options.cursorMcp ??
|
|
54824
|
-
cursorPluginDir: options.cursorPluginDir ??
|
|
55235
|
+
opencodeConfig: options.opencodeConfig ?? path14.join(home, ".config", "opencode", "opencode.json"),
|
|
55236
|
+
cursorSettings: options.cursorSettings ?? path14.join(home, ".cursor", "settings.json"),
|
|
55237
|
+
cursorMcp: options.cursorMcp ?? path14.join(home, ".cursor", "mcp.json"),
|
|
55238
|
+
cursorPluginDir: options.cursorPluginDir ?? path14.join(home, ".cursor", "plugins", "local", "workit")
|
|
54825
55239
|
};
|
|
54826
55240
|
};
|
|
54827
55241
|
function resolveApply(preview, options) {
|
|
@@ -54835,9 +55249,9 @@ var isRecord2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
|
54835
55249
|
var readExisting = (p) => {
|
|
54836
55250
|
let raw;
|
|
54837
55251
|
try {
|
|
54838
|
-
raw =
|
|
55252
|
+
raw = readFileSync12(p, "utf8");
|
|
54839
55253
|
} catch {
|
|
54840
|
-
if (
|
|
55254
|
+
if (existsSync11(p))
|
|
54841
55255
|
return { kind: "malformed", error: `${p} is not readable` };
|
|
54842
55256
|
return { kind: "missing" };
|
|
54843
55257
|
}
|
|
@@ -54861,7 +55275,7 @@ function deepMerge(base, patch) {
|
|
|
54861
55275
|
}
|
|
54862
55276
|
var readFileSafe = (p) => {
|
|
54863
55277
|
try {
|
|
54864
|
-
return
|
|
55278
|
+
return readFileSync12(p, "utf8");
|
|
54865
55279
|
} catch {
|
|
54866
55280
|
return null;
|
|
54867
55281
|
}
|
|
@@ -54877,7 +55291,7 @@ var workspaceEntriesAlreadyMatch = (contents, file, entries) => {
|
|
|
54877
55291
|
}
|
|
54878
55292
|
};
|
|
54879
55293
|
function applyMutation(m) {
|
|
54880
|
-
const dir =
|
|
55294
|
+
const dir = path14.dirname(m.path);
|
|
54881
55295
|
switch (m.type) {
|
|
54882
55296
|
case "create-file": {
|
|
54883
55297
|
mkdirSync5(dir, { recursive: true });
|
|
@@ -55026,7 +55440,7 @@ function applyMutation(m) {
|
|
|
55026
55440
|
detail: "already configured"
|
|
55027
55441
|
};
|
|
55028
55442
|
}
|
|
55029
|
-
mkdirSync5(
|
|
55443
|
+
mkdirSync5(path14.dirname(m.path), { recursive: true });
|
|
55030
55444
|
writeFileSync5(m.path, JSON.stringify(merged, null, 2) + `
|
|
55031
55445
|
`, "utf8");
|
|
55032
55446
|
return existing.kind === "record" ? { platform: "core", file: m.path, status: "Configured" } : { platform: "core", file: m.path, status: "Installed" };
|
|
@@ -55035,28 +55449,33 @@ function applyMutation(m) {
|
|
|
55035
55449
|
}
|
|
55036
55450
|
var isAdapter = (root, platform) => {
|
|
55037
55451
|
try {
|
|
55038
|
-
const pkg = JSON.parse(
|
|
55452
|
+
const pkg = JSON.parse(readFileSync12(path14.join(root, "package.json"), "utf8"));
|
|
55039
55453
|
return pkg.name === `@brainervirus/workit-${platform}`;
|
|
55040
55454
|
} catch {
|
|
55041
55455
|
return false;
|
|
55042
55456
|
}
|
|
55043
55457
|
};
|
|
55044
|
-
function adapterRoot(platform, res) {
|
|
55458
|
+
function adapterRoot(platform, res, preferInstalledAdapter = false) {
|
|
55045
55459
|
const candidates = [];
|
|
55460
|
+
const stagedCursor = path14.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap", "node_modules", "@brainervirus", "workit-cursor");
|
|
55461
|
+
if (platform === "cursor" && preferInstalledAdapter)
|
|
55462
|
+
candidates.push(stagedCursor);
|
|
55046
55463
|
if (res.dev) {
|
|
55047
|
-
candidates.push(
|
|
55464
|
+
candidates.push(path14.join(res.dev, "packages", `workit-${platform}`));
|
|
55048
55465
|
} else {
|
|
55049
|
-
candidates.push(
|
|
55050
|
-
let dir =
|
|
55466
|
+
candidates.push(path14.join(packageRoot(), "..", `workit-${platform}`));
|
|
55467
|
+
let dir = path14.resolve(res.cwd);
|
|
55051
55468
|
while (true) {
|
|
55052
|
-
candidates.push(
|
|
55053
|
-
const parent =
|
|
55469
|
+
candidates.push(path14.join(dir, "packages", `workit-${platform}`));
|
|
55470
|
+
const parent = path14.dirname(dir);
|
|
55054
55471
|
if (parent === dir)
|
|
55055
55472
|
break;
|
|
55056
55473
|
dir = parent;
|
|
55057
55474
|
}
|
|
55058
55475
|
}
|
|
55059
|
-
candidates.push(
|
|
55476
|
+
candidates.push(path14.join(res.home, ".local", "share", "workit", "packages", `workit-${platform}`));
|
|
55477
|
+
if (platform === "cursor")
|
|
55478
|
+
candidates.push(stagedCursor);
|
|
55060
55479
|
for (const candidate of candidates) {
|
|
55061
55480
|
if (isAdapter(candidate, platform))
|
|
55062
55481
|
return candidate;
|
|
@@ -55073,16 +55492,16 @@ var resolveOpenCodePin = (root, opts = {}) => {
|
|
|
55073
55492
|
if (!isDevOpenCodeAdapterRoot(root, opts.dev))
|
|
55074
55493
|
return OPENCODE_NPM_PIN;
|
|
55075
55494
|
for (const rel of ["src/plugin.ts", "dist/plugin.js"]) {
|
|
55076
|
-
const entry =
|
|
55077
|
-
if (
|
|
55495
|
+
const entry = path14.join(root, rel);
|
|
55496
|
+
if (existsSync11(entry))
|
|
55078
55497
|
return `file://${entry}`;
|
|
55079
55498
|
}
|
|
55080
55499
|
return null;
|
|
55081
55500
|
};
|
|
55082
55501
|
var opencodePin = (root, res) => resolveOpenCodePin(root, { dev: res.dev });
|
|
55083
55502
|
function applyOpenCode(root, res) {
|
|
55084
|
-
const
|
|
55085
|
-
if (!
|
|
55503
|
+
const resolvedPin = opencodePin(root, res);
|
|
55504
|
+
if (!resolvedPin) {
|
|
55086
55505
|
return {
|
|
55087
55506
|
platform: "opencode",
|
|
55088
55507
|
file: res.opencodeConfig,
|
|
@@ -55090,7 +55509,7 @@ function applyOpenCode(root, res) {
|
|
|
55090
55509
|
detail: "workit-opencode package has no loadable plugin entry (src/plugin.ts or dist/plugin.js)"
|
|
55091
55510
|
};
|
|
55092
55511
|
}
|
|
55093
|
-
mkdirSync5(
|
|
55512
|
+
mkdirSync5(path14.dirname(res.opencodeConfig), { recursive: true });
|
|
55094
55513
|
const existing = readExisting(res.opencodeConfig);
|
|
55095
55514
|
if (existing.kind === "malformed") {
|
|
55096
55515
|
return {
|
|
@@ -55100,7 +55519,17 @@ function applyOpenCode(root, res) {
|
|
|
55100
55519
|
detail: `cannot merge into malformed config: ${existing.error} — repair or remove the file`
|
|
55101
55520
|
};
|
|
55102
55521
|
}
|
|
55103
|
-
const
|
|
55522
|
+
const configuredPlugins = existing.kind === "record" ? Array.isArray(existing.value.plugins) ? existing.value.plugins : typeof existing.value.plugins === "string" ? [existing.value.plugins] : typeof existing.value.plugin === "string" ? [existing.value.plugin] : Array.isArray(existing.value.plugin) ? existing.value.plugin : [] : [];
|
|
55523
|
+
const configuredPin = configuredPlugins.find((entry) => typeof entry === "string" && isWorkitPlugin(entry));
|
|
55524
|
+
const pin = configuredPin ?? resolvedPin;
|
|
55525
|
+
const base = existing.kind === "record" ? existing.value : {};
|
|
55526
|
+
const merged = existing.kind === "record" && Object.hasOwn(existing.value, "plugins") ? (() => {
|
|
55527
|
+
const plugins = mergeOpenCodePlugins(existing.value.plugins, pin);
|
|
55528
|
+
return {
|
|
55529
|
+
config: { ...existing.value, plugins: plugins.config },
|
|
55530
|
+
changed: plugins.changed.length > 0 ? ["plugins"] : []
|
|
55531
|
+
};
|
|
55532
|
+
})() : mergeOpenCodeConfig(base, pin);
|
|
55104
55533
|
if (merged.changed.length === 0) {
|
|
55105
55534
|
return {
|
|
55106
55535
|
platform: "opencode",
|
|
@@ -55125,22 +55554,22 @@ function applyOpenCode(root, res) {
|
|
|
55125
55554
|
}
|
|
55126
55555
|
var samePluginContent = (src, dest, relative = "") => {
|
|
55127
55556
|
try {
|
|
55128
|
-
for (const entry of
|
|
55557
|
+
for (const entry of readdirSync5(src, { withFileTypes: true })) {
|
|
55129
55558
|
if (entry.name === "node_modules")
|
|
55130
55559
|
continue;
|
|
55131
|
-
const source =
|
|
55132
|
-
const installed =
|
|
55560
|
+
const source = path14.join(src, entry.name);
|
|
55561
|
+
const installed = path14.join(dest, entry.name);
|
|
55133
55562
|
if (entry.isDirectory()) {
|
|
55134
|
-
if (!
|
|
55563
|
+
if (!statSync4(installed).isDirectory() || !samePluginContent(source, installed, path14.join(relative, entry.name)))
|
|
55135
55564
|
return false;
|
|
55136
|
-
} else if (!
|
|
55565
|
+
} else if (!readFileSync12(source).equals(readFileSync12(installed))) {
|
|
55137
55566
|
return false;
|
|
55138
55567
|
}
|
|
55139
55568
|
}
|
|
55140
|
-
for (const entry of
|
|
55141
|
-
if (
|
|
55569
|
+
for (const entry of readdirSync5(dest, { withFileTypes: true })) {
|
|
55570
|
+
if (existsSync11(path14.join(src, entry.name)))
|
|
55142
55571
|
continue;
|
|
55143
|
-
const rel =
|
|
55572
|
+
const rel = path14.join(relative, entry.name);
|
|
55144
55573
|
if (rel === ".workit-root")
|
|
55145
55574
|
continue;
|
|
55146
55575
|
if (relative === "rules" && entry.isFile() && entry.name.endsWith(".mdc"))
|
|
@@ -55154,43 +55583,43 @@ var samePluginContent = (src, dest, relative = "") => {
|
|
|
55154
55583
|
};
|
|
55155
55584
|
var preservedCursorRules = (src, dest) => {
|
|
55156
55585
|
const preserved = new Map;
|
|
55157
|
-
const sourceRules =
|
|
55158
|
-
const installedRules =
|
|
55586
|
+
const sourceRules = path14.join(src, "rules");
|
|
55587
|
+
const installedRules = path14.join(dest, "rules");
|
|
55159
55588
|
try {
|
|
55160
|
-
for (const entry of
|
|
55589
|
+
for (const entry of readdirSync5(installedRules, { withFileTypes: true })) {
|
|
55161
55590
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
55162
55591
|
continue;
|
|
55163
|
-
if (
|
|
55592
|
+
if (existsSync11(path14.join(sourceRules, entry.name)))
|
|
55164
55593
|
continue;
|
|
55165
|
-
preserved.set(entry.name,
|
|
55594
|
+
preserved.set(entry.name, readFileSync12(path14.join(installedRules, entry.name)));
|
|
55166
55595
|
}
|
|
55167
55596
|
} catch {}
|
|
55168
55597
|
return preserved;
|
|
55169
55598
|
};
|
|
55170
55599
|
function copyPluginDir(src, dest) {
|
|
55171
55600
|
const realSrc = realpathSync2(src);
|
|
55172
|
-
const marker =
|
|
55173
|
-
const destIsLink =
|
|
55601
|
+
const marker = path14.join(dest, ".workit-root");
|
|
55602
|
+
const destIsLink = existsSync11(dest) && lstatSync4(dest).isSymbolicLink();
|
|
55174
55603
|
const synced = !destIsLink && readFileSafe(marker)?.trim() === realSrc && samePluginContent(realSrc, dest);
|
|
55175
55604
|
if (synced)
|
|
55176
55605
|
return "Skipped";
|
|
55177
|
-
const hadDir =
|
|
55606
|
+
const hadDir = existsSync11(dest);
|
|
55178
55607
|
const rules = preservedCursorRules(realSrc, dest);
|
|
55179
|
-
const parent =
|
|
55608
|
+
const parent = path14.dirname(dest);
|
|
55180
55609
|
mkdirSync5(parent, { recursive: true });
|
|
55181
|
-
const swap = mkdtempSync(
|
|
55182
|
-
const stage =
|
|
55183
|
-
const backup =
|
|
55610
|
+
const swap = mkdtempSync(path14.join(parent, `.${path14.basename(dest)}.swap-`));
|
|
55611
|
+
const stage = path14.join(swap, "stage");
|
|
55612
|
+
const backup = path14.join(swap, "backup");
|
|
55184
55613
|
try {
|
|
55185
55614
|
cpSync3(realSrc, stage, {
|
|
55186
55615
|
recursive: true,
|
|
55187
|
-
filter: (entry) => !
|
|
55616
|
+
filter: (entry) => !path14.relative(realSrc, entry).split(path14.sep).includes("node_modules")
|
|
55188
55617
|
});
|
|
55189
55618
|
for (const [name, content] of rules) {
|
|
55190
|
-
mkdirSync5(
|
|
55191
|
-
writeFileSync5(
|
|
55619
|
+
mkdirSync5(path14.join(stage, "rules"), { recursive: true });
|
|
55620
|
+
writeFileSync5(path14.join(stage, "rules", name), content);
|
|
55192
55621
|
}
|
|
55193
|
-
writeFileSync5(
|
|
55622
|
+
writeFileSync5(path14.join(stage, ".workit-root"), realSrc + `
|
|
55194
55623
|
`, "utf8");
|
|
55195
55624
|
if (!samePluginContent(realSrc, stage))
|
|
55196
55625
|
throw new Error("staged adapter content is incomplete");
|
|
@@ -55202,7 +55631,7 @@ function copyPluginDir(src, dest) {
|
|
|
55202
55631
|
try {
|
|
55203
55632
|
renameSync2(stage, dest);
|
|
55204
55633
|
} catch (error) {
|
|
55205
|
-
if (hadDir && !
|
|
55634
|
+
if (hadDir && !existsSync11(dest))
|
|
55206
55635
|
renameSync2(backup, dest);
|
|
55207
55636
|
throw error;
|
|
55208
55637
|
}
|
|
@@ -55213,26 +55642,26 @@ function copyPluginDir(src, dest) {
|
|
|
55213
55642
|
return hadDir ? "Configured" : "Installed";
|
|
55214
55643
|
}
|
|
55215
55644
|
var removeLegacyCursorDir = (res) => {
|
|
55216
|
-
const legacy =
|
|
55217
|
-
if (legacy === res.cursorPluginDir || !
|
|
55645
|
+
const legacy = path14.join(res.home, ".cursor", "plugins", "local", "workflow-toolkit");
|
|
55646
|
+
if (legacy === res.cursorPluginDir || !existsSync11(legacy))
|
|
55218
55647
|
return;
|
|
55219
|
-
const legacyRules =
|
|
55220
|
-
if (
|
|
55648
|
+
const legacyRules = path14.join(legacy, "rules");
|
|
55649
|
+
if (existsSync11(legacyRules)) {
|
|
55221
55650
|
try {
|
|
55222
|
-
mkdirSync5(
|
|
55223
|
-
for (const entry of
|
|
55651
|
+
mkdirSync5(path14.join(res.cursorPluginDir, "rules"), { recursive: true });
|
|
55652
|
+
for (const entry of readdirSync5(legacyRules, { withFileTypes: true })) {
|
|
55224
55653
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
55225
55654
|
continue;
|
|
55226
|
-
const target =
|
|
55227
|
-
if (!
|
|
55228
|
-
copyFileSync2(
|
|
55655
|
+
const target = path14.join(res.cursorPluginDir, "rules", entry.name);
|
|
55656
|
+
if (!existsSync11(target))
|
|
55657
|
+
copyFileSync2(path14.join(legacyRules, entry.name), target);
|
|
55229
55658
|
}
|
|
55230
55659
|
} catch {}
|
|
55231
55660
|
}
|
|
55232
55661
|
rmSync(legacy, { recursive: true, force: true });
|
|
55233
55662
|
};
|
|
55234
55663
|
function applyCursorSettings(root, res) {
|
|
55235
|
-
mkdirSync5(
|
|
55664
|
+
mkdirSync5(path14.dirname(res.cursorSettings), { recursive: true });
|
|
55236
55665
|
const settingsExisting = readExisting(res.cursorSettings);
|
|
55237
55666
|
if (settingsExisting.kind === "malformed") {
|
|
55238
55667
|
return {
|
|
@@ -55260,7 +55689,7 @@ function applyCursorSettings(root, res) {
|
|
|
55260
55689
|
};
|
|
55261
55690
|
}
|
|
55262
55691
|
function applyCursorMcp(root, res) {
|
|
55263
|
-
mkdirSync5(
|
|
55692
|
+
mkdirSync5(path14.dirname(res.cursorMcp), { recursive: true });
|
|
55264
55693
|
const mcpExisting = readExisting(res.cursorMcp);
|
|
55265
55694
|
if (mcpExisting.kind === "malformed") {
|
|
55266
55695
|
return {
|
|
@@ -55270,7 +55699,18 @@ function applyCursorMcp(root, res) {
|
|
|
55270
55699
|
detail: `cannot merge into malformed config: ${mcpExisting.error} — repair or remove the file`
|
|
55271
55700
|
};
|
|
55272
55701
|
}
|
|
55273
|
-
const
|
|
55702
|
+
const mcpBase = mcpExisting.kind === "record" ? mcpExisting.value : {};
|
|
55703
|
+
const server = cursorMcpServerEntry(res.cursorPluginDir);
|
|
55704
|
+
const servers = isRecord2(mcpBase.mcpServers) ? mcpBase.mcpServers : {};
|
|
55705
|
+
const current = isRecord2(servers.workit) ? servers.workit : {};
|
|
55706
|
+
const previousArgs = Array.isArray(current.args) ? current.args.map(String) : [];
|
|
55707
|
+
const previousPackage = previousArgs.find((arg) => arg.startsWith("--package=@brainervirus/workit-cursor@") && arg !== `--package=${CURSOR_RUNTIME_PACKAGE}`);
|
|
55708
|
+
if (previousPackage) {
|
|
55709
|
+
const index = server.args.findIndex((arg) => arg.startsWith("--package="));
|
|
55710
|
+
if (index >= 0)
|
|
55711
|
+
server.args[index] = previousPackage;
|
|
55712
|
+
}
|
|
55713
|
+
const mcp = mergeCursorMcp(mcpBase, "workit", server);
|
|
55274
55714
|
if (mcp.changed.length === 0) {
|
|
55275
55715
|
return {
|
|
55276
55716
|
platform: "cursor",
|
|
@@ -55288,9 +55728,9 @@ function applyCursorMcp(root, res) {
|
|
|
55288
55728
|
};
|
|
55289
55729
|
}
|
|
55290
55730
|
function verifyPlatform(platform, res) {
|
|
55291
|
-
if (platform === "opencode" && !
|
|
55731
|
+
if (platform === "opencode" && !existsSync11(res.opencodeConfig))
|
|
55292
55732
|
return null;
|
|
55293
|
-
if (platform === "cursor" && !
|
|
55733
|
+
if (platform === "cursor" && !existsSync11(res.cursorSettings) && !existsSync11(res.cursorMcp)) {
|
|
55294
55734
|
return null;
|
|
55295
55735
|
}
|
|
55296
55736
|
return runDoctor({
|
|
@@ -55355,6 +55795,51 @@ function applySetupPreview(preview, options = {}) {
|
|
|
55355
55795
|
const rootFor = new Map;
|
|
55356
55796
|
let cursorCopyOk = false;
|
|
55357
55797
|
for (const mutation of preview.mutations) {
|
|
55798
|
+
if (mutation.type === "install-host") {
|
|
55799
|
+
const expectedPath = mutation.platform === "cursor" ? path14.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap") : mutation.platform === "codex" ? path14.join(res.env.CODEX_HOME ?? path14.join(res.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : mutation.platform === "pi" ? path14.join(res.env.PI_CODING_AGENT_DIR ?? path14.join(res.home, ".pi", "agent"), "settings.json") : "";
|
|
55800
|
+
if (mutation.path !== expectedPath) {
|
|
55801
|
+
entries.push({
|
|
55802
|
+
platform: mutation.platform,
|
|
55803
|
+
file: mutation.path,
|
|
55804
|
+
status: "Failed",
|
|
55805
|
+
detail: `preview/apply path mismatch: apply resolved ${expectedPath}, the previewed host install was ${mutation.path} — rebuild the preview with the same options`
|
|
55806
|
+
});
|
|
55807
|
+
continue;
|
|
55808
|
+
}
|
|
55809
|
+
const run = options.runHostCommand ?? ((step) => runHostCommand(step, { home: res.home, env: res.env }));
|
|
55810
|
+
const installed = runHostInstall(mutation.commands, run);
|
|
55811
|
+
for (const { command, result } of installed.results) {
|
|
55812
|
+
entries.push({
|
|
55813
|
+
platform: mutation.platform,
|
|
55814
|
+
file: command.command,
|
|
55815
|
+
status: result.exitCode === 0 ? "Installed" : "Failed",
|
|
55816
|
+
detail: result.exitCode === 0 ? `${command.purpose} (${command.args.join(" ")})` : `${command.purpose} failed (${command.args.join(" ")}): ${result.stderr || `exit ${result.exitCode}`}`
|
|
55817
|
+
});
|
|
55818
|
+
}
|
|
55819
|
+
if (!installed.ok && installed.results.length === 0) {
|
|
55820
|
+
entries.push({
|
|
55821
|
+
platform: mutation.platform,
|
|
55822
|
+
file: mutation.platform,
|
|
55823
|
+
status: "Failed",
|
|
55824
|
+
detail: "host installation did not run"
|
|
55825
|
+
});
|
|
55826
|
+
}
|
|
55827
|
+
if (!installed.ok)
|
|
55828
|
+
continue;
|
|
55829
|
+
if (mutation.platform === "cursor" && installed.packageRoot) {
|
|
55830
|
+
rootFor.set("cursor", installed.packageRoot);
|
|
55831
|
+
}
|
|
55832
|
+
const verified = mutation.platform === "codex" ? isCodexWorkitInstalled(res.home, res.env) : mutation.platform === "pi" ? isPiWorkitInstalled(res.home, res.env) : true;
|
|
55833
|
+
if (!verified) {
|
|
55834
|
+
entries.push({
|
|
55835
|
+
platform: mutation.platform,
|
|
55836
|
+
file: mutation.platform,
|
|
55837
|
+
status: "Failed",
|
|
55838
|
+
detail: "the host command succeeded, but Workit registration was not found; inspect the host's native package list and retry"
|
|
55839
|
+
});
|
|
55840
|
+
}
|
|
55841
|
+
continue;
|
|
55842
|
+
}
|
|
55358
55843
|
if (mutation.type !== "register-platform" && mutation.type !== "install-adapter") {
|
|
55359
55844
|
entries.push(applyMutation(mutation));
|
|
55360
55845
|
continue;
|
|
@@ -55372,7 +55857,7 @@ function applySetupPreview(preview, options = {}) {
|
|
|
55372
55857
|
}
|
|
55373
55858
|
let root = rootFor.get(platform);
|
|
55374
55859
|
if (root === undefined) {
|
|
55375
|
-
root = adapterRoot(platform, res);
|
|
55860
|
+
root = adapterRoot(platform, res, options.preferInstalledAdapter);
|
|
55376
55861
|
rootFor.set(platform, root);
|
|
55377
55862
|
}
|
|
55378
55863
|
if (root === null) {
|
|
@@ -55468,7 +55953,7 @@ var setupCompletionGuidance = () => [
|
|
|
55468
55953
|
];
|
|
55469
55954
|
function applyWorkspaceBranchPolicy(opts) {
|
|
55470
55955
|
const { workspace_root, env = process.env } = opts;
|
|
55471
|
-
const dir =
|
|
55956
|
+
const dir = path14.join(env.WORKFLOW_TOOLKIT_CONFIG ?? configDir());
|
|
55472
55957
|
const {
|
|
55473
55958
|
status,
|
|
55474
55959
|
path: wsPath,
|
|
@@ -55480,7 +55965,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
55480
55965
|
if (status === "malformed" || status === "invalid")
|
|
55481
55966
|
return { ok: false, error: workspacesError ?? `invalid workspaces.json: ${wsPath}` };
|
|
55482
55967
|
const detection = detectBranchPolicy(workspace_root);
|
|
55483
|
-
const name = String(env.WORKFLOW_BP_NAME ??
|
|
55968
|
+
const name = String(env.WORKFLOW_BP_NAME ?? path14.basename(workspace_root));
|
|
55484
55969
|
const integration = env.WORKFLOW_BP_INTEGRATION ?? detection.integration;
|
|
55485
55970
|
const policy = {
|
|
55486
55971
|
preset: detection.preset,
|
|
@@ -55529,7 +56014,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
55529
56014
|
ok: false,
|
|
55530
56015
|
error: `workspaces.json changed while applying the branch policy: ${wsPath}`
|
|
55531
56016
|
};
|
|
55532
|
-
mkdirSync5(
|
|
56017
|
+
mkdirSync5(path14.dirname(wsPath), { recursive: true });
|
|
55533
56018
|
const tmp = `${wsPath}.${process.pid}.tmp`;
|
|
55534
56019
|
try {
|
|
55535
56020
|
writeFileSync5(tmp, JSON.stringify({ ...document2, workspaces: next }, null, 2) + `
|
|
@@ -55588,6 +56073,201 @@ function validateBaseUrl(url) {
|
|
|
55588
56073
|
return "base URL must use https";
|
|
55589
56074
|
return null;
|
|
55590
56075
|
}
|
|
56076
|
+
function workspaceEditorValue(workspace, field) {
|
|
56077
|
+
const [section, key, leaf] = field.split(".");
|
|
56078
|
+
if (section === "defaultProfile")
|
|
56079
|
+
return workspace.defaultProfile ?? "";
|
|
56080
|
+
if (section === "vcs") {
|
|
56081
|
+
if (key === "account")
|
|
56082
|
+
return workspace.vcs?.account ?? "";
|
|
56083
|
+
return workspace.vcs?.defaultTargetBranch ?? "";
|
|
56084
|
+
}
|
|
56085
|
+
if (section === "youtrack")
|
|
56086
|
+
return key === "baseUrl" ? workspace.youtrack?.baseUrl ?? "" : workspace.youtrack?.link_issues === undefined ? "inherit" : String(workspace.youtrack.link_issues);
|
|
56087
|
+
if (section === "issues")
|
|
56088
|
+
return workspace.issues?.link_on_pr === undefined ? "inherit" : String(workspace.issues.link_on_pr);
|
|
56089
|
+
if (section === "branchPolicy") {
|
|
56090
|
+
const value = workspace.branchPolicy;
|
|
56091
|
+
if (key === "preset")
|
|
56092
|
+
return value?.preset ?? "inherit";
|
|
56093
|
+
if (key === "allowed")
|
|
56094
|
+
return value?.allowed?.join(", ") ?? "";
|
|
56095
|
+
if (key === "protected")
|
|
56096
|
+
return value?.protected?.join(", ") ?? "";
|
|
56097
|
+
if (key === "developBranch")
|
|
56098
|
+
return value?.developBranch ?? "";
|
|
56099
|
+
if (key === "integration")
|
|
56100
|
+
return value?.integration ?? "merge";
|
|
56101
|
+
if (key === "prefixes")
|
|
56102
|
+
return value?.prefixes?.[leaf] ?? "";
|
|
56103
|
+
}
|
|
56104
|
+
if (section === "commitPolicy") {
|
|
56105
|
+
if (key === "preset")
|
|
56106
|
+
return workspace.commitPolicy?.preset ?? "inherit";
|
|
56107
|
+
if (key === "pattern")
|
|
56108
|
+
return workspace.commitPolicy?.pattern ?? "";
|
|
56109
|
+
}
|
|
56110
|
+
return "";
|
|
56111
|
+
}
|
|
56112
|
+
function setWorkspaceEditorValue(workspace, field, value, defaults = {}) {
|
|
56113
|
+
const [section, key, leaf] = field.split(".");
|
|
56114
|
+
const list = value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
56115
|
+
if (section === "defaultProfile")
|
|
56116
|
+
return { ...workspace, defaultProfile: value.trim() || undefined };
|
|
56117
|
+
if (section === "vcs")
|
|
56118
|
+
return workspace.vcs ? { ...workspace, vcs: { ...workspace.vcs, [key]: value.trim() || undefined } } : workspace;
|
|
56119
|
+
if (section === "youtrack") {
|
|
56120
|
+
const current = workspace.youtrack ?? {};
|
|
56121
|
+
if (key === "baseUrl")
|
|
56122
|
+
return { ...workspace, youtrack: { ...current, baseUrl: value.trim() || undefined } };
|
|
56123
|
+
if (!value || value === "inherit") {
|
|
56124
|
+
const { link_issues: _discard, ...rest } = current;
|
|
56125
|
+
return { ...workspace, youtrack: Object.keys(rest).length ? rest : undefined };
|
|
56126
|
+
}
|
|
56127
|
+
return { ...workspace, youtrack: { ...current, link_issues: value === "true" } };
|
|
56128
|
+
}
|
|
56129
|
+
if (section === "issues") {
|
|
56130
|
+
const current = workspace.issues ?? { provider: "github" };
|
|
56131
|
+
if (!value || value === "inherit") {
|
|
56132
|
+
const { link_on_pr: _discard, ...rest } = current;
|
|
56133
|
+
return { ...workspace, issues: Object.keys(rest).length ? rest : undefined };
|
|
56134
|
+
}
|
|
56135
|
+
return {
|
|
56136
|
+
...workspace,
|
|
56137
|
+
issues: { ...current, provider: "github", link_on_pr: value === "true" }
|
|
56138
|
+
};
|
|
56139
|
+
}
|
|
56140
|
+
if (section === "branchPolicy") {
|
|
56141
|
+
if (key === "preset" && (!value.trim() || value === "inherit")) {
|
|
56142
|
+
const { branchPolicy: _discard, ...rest } = workspace;
|
|
56143
|
+
return rest;
|
|
56144
|
+
}
|
|
56145
|
+
const current = workspace.branchPolicy ?? { preset: defaults.branchPreset ?? "gitflow" };
|
|
56146
|
+
const branchPolicy = key === "preset" ? { ...current, preset: value || "gitflow" } : key === "allowed" ? { ...current, allowed: list } : key === "protected" ? { ...current, protected: list } : key === "developBranch" ? { ...current, developBranch: value.trim() || undefined } : key === "integration" ? { ...current, integration: value === "pr" ? "pr" : "merge" } : key === "prefixes" ? {
|
|
56147
|
+
...current,
|
|
56148
|
+
prefixes: {
|
|
56149
|
+
feature: "feature/",
|
|
56150
|
+
bugfix: "bugfix/",
|
|
56151
|
+
release: "release/",
|
|
56152
|
+
hotfix: "hotfix/",
|
|
56153
|
+
...current.prefixes,
|
|
56154
|
+
[leaf]: value.trim()
|
|
56155
|
+
}
|
|
56156
|
+
} : current;
|
|
56157
|
+
return { ...workspace, branchPolicy };
|
|
56158
|
+
}
|
|
56159
|
+
if (section === "commitPolicy") {
|
|
56160
|
+
if (key === "preset" && (!value.trim() || value === "inherit")) {
|
|
56161
|
+
const { commitPolicy: _discard, ...rest } = workspace;
|
|
56162
|
+
return rest;
|
|
56163
|
+
}
|
|
56164
|
+
const current = workspace.commitPolicy ?? { preset: defaults.commitPreset ?? "conventional" };
|
|
56165
|
+
return {
|
|
56166
|
+
...workspace,
|
|
56167
|
+
commitPolicy: key === "pattern" ? { ...current, pattern: value || undefined } : { ...current, preset: value }
|
|
56168
|
+
};
|
|
56169
|
+
}
|
|
56170
|
+
return workspace;
|
|
56171
|
+
}
|
|
56172
|
+
var splitList = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
56173
|
+
var emptyTrack = () => ({
|
|
56174
|
+
strategy: "gitflow",
|
|
56175
|
+
productionBranch: "main",
|
|
56176
|
+
integrationBranch: "develop",
|
|
56177
|
+
naming: { feature: "feature/{name}", release: "release/{version}", hotfix: "hotfix/{name}" },
|
|
56178
|
+
baseBranch: "develop",
|
|
56179
|
+
mergeBackBranches: ["develop"],
|
|
56180
|
+
pullRequestTarget: "develop",
|
|
56181
|
+
tagNamespace: "",
|
|
56182
|
+
versionSource: { kind: "git-tag" },
|
|
56183
|
+
requiredChecks: []
|
|
56184
|
+
});
|
|
56185
|
+
function profileEditorValue(profile, field) {
|
|
56186
|
+
const [section, key, leaf] = field.split(".");
|
|
56187
|
+
if (section === "branchPolicy") {
|
|
56188
|
+
const value = profile?.branchPolicy;
|
|
56189
|
+
if (key === "prefixes")
|
|
56190
|
+
return value?.prefixes?.[leaf] ?? "";
|
|
56191
|
+
if (key === "allowed" || key === "protected")
|
|
56192
|
+
return value?.[key]?.join(", ") ?? "";
|
|
56193
|
+
return String(value?.[key] ?? "");
|
|
56194
|
+
}
|
|
56195
|
+
return String(profile?.commitPolicy?.[key] ?? "");
|
|
56196
|
+
}
|
|
56197
|
+
function setProfileEditorValue(profile, field, value, defaults = {}) {
|
|
56198
|
+
const [section, key, leaf] = field.split(".");
|
|
56199
|
+
if (section === "branchPolicy") {
|
|
56200
|
+
if (key === "preset" && (!value.trim() || value === "inherit")) {
|
|
56201
|
+
const { branchPolicy: _discard, ...rest } = profile;
|
|
56202
|
+
return rest;
|
|
56203
|
+
}
|
|
56204
|
+
const current = profile.branchPolicy ?? { preset: defaults.branchPreset ?? "gitflow" };
|
|
56205
|
+
let branchPolicy;
|
|
56206
|
+
if (key === "preset")
|
|
56207
|
+
branchPolicy = { ...current, preset: value || "gitflow" };
|
|
56208
|
+
else if (key === "allowed" || key === "protected")
|
|
56209
|
+
branchPolicy = { ...current, [key]: splitList(value) };
|
|
56210
|
+
else if (key === "prefixes")
|
|
56211
|
+
branchPolicy = {
|
|
56212
|
+
...current,
|
|
56213
|
+
prefixes: {
|
|
56214
|
+
feature: "feature/",
|
|
56215
|
+
bugfix: "bugfix/",
|
|
56216
|
+
release: "release/",
|
|
56217
|
+
hotfix: "hotfix/",
|
|
56218
|
+
...current.prefixes,
|
|
56219
|
+
[leaf]: value
|
|
56220
|
+
}
|
|
56221
|
+
};
|
|
56222
|
+
else if (key === "developBranch")
|
|
56223
|
+
branchPolicy = { ...current, developBranch: value || undefined };
|
|
56224
|
+
else
|
|
56225
|
+
branchPolicy = { ...current, integration: value === "pr" ? "pr" : "merge" };
|
|
56226
|
+
return { ...profile, branchPolicy };
|
|
56227
|
+
}
|
|
56228
|
+
const current = profile.commitPolicy ?? { preset: defaults.commitPreset ?? "conventional" };
|
|
56229
|
+
if (key === "preset" && (!value.trim() || value === "inherit")) {
|
|
56230
|
+
const { commitPolicy: _discard, ...rest } = profile;
|
|
56231
|
+
return rest;
|
|
56232
|
+
}
|
|
56233
|
+
return {
|
|
56234
|
+
...profile,
|
|
56235
|
+
commitPolicy: key === "pattern" ? { ...current, pattern: value || undefined } : { ...current, preset: value || "conventional" }
|
|
56236
|
+
};
|
|
56237
|
+
}
|
|
56238
|
+
function trackEditorValue(track, field) {
|
|
56239
|
+
if (field.startsWith("naming."))
|
|
56240
|
+
return track.naming[field.slice(7)];
|
|
56241
|
+
if (field === "mergeBackBranches" || field === "requiredChecks")
|
|
56242
|
+
return track[field].join(", ");
|
|
56243
|
+
if (field.startsWith("versionSource.")) {
|
|
56244
|
+
const key = field.slice(14);
|
|
56245
|
+
if (key === "kind")
|
|
56246
|
+
return track.versionSource.kind;
|
|
56247
|
+
if (key === "path")
|
|
56248
|
+
return track.versionSource.kind === "package-json" ? track.versionSource.path : "";
|
|
56249
|
+
return track.versionSource.kind === "package-json" ? track.versionSource.field : "";
|
|
56250
|
+
}
|
|
56251
|
+
return String(track[field] ?? "");
|
|
56252
|
+
}
|
|
56253
|
+
function setTrackEditorValue(track, field, value) {
|
|
56254
|
+
if (field.startsWith("naming."))
|
|
56255
|
+
return { ...track, naming: { ...track.naming, [field.slice(7)]: value } };
|
|
56256
|
+
if (field === "mergeBackBranches" || field === "requiredChecks")
|
|
56257
|
+
return { ...track, [field]: splitList(value) };
|
|
56258
|
+
if (field.startsWith("versionSource.")) {
|
|
56259
|
+
const key = field.slice(14);
|
|
56260
|
+
const kind = key === "kind" ? value : track.versionSource.kind;
|
|
56261
|
+
const versionSource = kind === "package-json" ? {
|
|
56262
|
+
kind,
|
|
56263
|
+
path: key === "path" ? value : track.versionSource.kind === kind ? track.versionSource.path : "package.json",
|
|
56264
|
+
field: key === "field" ? value : track.versionSource.kind === kind ? track.versionSource.field : "version"
|
|
56265
|
+
} : kind === "manual" ? { kind } : { kind: "git-tag" };
|
|
56266
|
+
return { ...track, versionSource };
|
|
56267
|
+
}
|
|
56268
|
+
return { ...track, [field]: value };
|
|
56269
|
+
}
|
|
56270
|
+
var createReleaseTrack = emptyTrack;
|
|
55591
56271
|
function loadWorkspaces() {
|
|
55592
56272
|
return loadWorkspacesFrom(configDir());
|
|
55593
56273
|
}
|
|
@@ -55605,8 +56285,8 @@ function applyWizardBranchPolicy(branchPolicy, workspace_root, env = process.env
|
|
|
55605
56285
|
}
|
|
55606
56286
|
|
|
55607
56287
|
// packages/workit-cli/src/wizard-state.ts
|
|
55608
|
-
import { existsSync as
|
|
55609
|
-
import
|
|
56288
|
+
import { existsSync as existsSync12, statSync as statSync5 } from "node:fs";
|
|
56289
|
+
import path15 from "node:path";
|
|
55610
56290
|
import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
|
|
55611
56291
|
var NEXT = {
|
|
55612
56292
|
platforms: "locale",
|
|
@@ -55625,6 +56305,10 @@ var NEXT = {
|
|
|
55625
56305
|
workspaceName: "workspaceGlob",
|
|
55626
56306
|
workspaceGlob: "workspaceProvider",
|
|
55627
56307
|
workspaceProvider: null,
|
|
56308
|
+
workspaceAdvanced: null,
|
|
56309
|
+
workspaceAdvancedValue: null,
|
|
56310
|
+
globalCommitPolicy: null,
|
|
56311
|
+
globalCommitPattern: null,
|
|
55628
56312
|
branchPolicy: "project",
|
|
55629
56313
|
branchPolicyDevelop: "branchPolicy",
|
|
55630
56314
|
project: "summary",
|
|
@@ -55648,6 +56332,10 @@ var PREV = {
|
|
|
55648
56332
|
workspaceName: "workspaces",
|
|
55649
56333
|
workspaceGlob: "workspaceName",
|
|
55650
56334
|
workspaceProvider: "workspaceGlob",
|
|
56335
|
+
workspaceAdvanced: "workspaces",
|
|
56336
|
+
workspaceAdvancedValue: "workspaceAdvanced",
|
|
56337
|
+
globalCommitPolicy: "workspaces",
|
|
56338
|
+
globalCommitPattern: "globalCommitPolicy",
|
|
55651
56339
|
branchPolicy: "workspaces",
|
|
55652
56340
|
branchPolicyDevelop: "branchPolicy",
|
|
55653
56341
|
project: "branchPolicy",
|
|
@@ -55662,7 +56350,7 @@ function resolveBasePath(values, env = process.env) {
|
|
|
55662
56350
|
}
|
|
55663
56351
|
var isDirectory = (p) => {
|
|
55664
56352
|
try {
|
|
55665
|
-
return
|
|
56353
|
+
return statSync5(p).isDirectory();
|
|
55666
56354
|
} catch {
|
|
55667
56355
|
return false;
|
|
55668
56356
|
}
|
|
@@ -55671,9 +56359,9 @@ var basePathMessage = (value) => {
|
|
|
55671
56359
|
const p = value.trim();
|
|
55672
56360
|
if (!p)
|
|
55673
56361
|
return "workspace root path is required";
|
|
55674
|
-
return !
|
|
56362
|
+
return !path15.isAbsolute(p) || !isDirectory(p) ? `invalid workspace root "${p}" — enter an existing absolute directory` : null;
|
|
55675
56363
|
};
|
|
55676
|
-
var skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !
|
|
56364
|
+
var skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync12(path15.join(basePath, ".git"));
|
|
55677
56365
|
function nextScreen(screen, preset, tracker, basePath) {
|
|
55678
56366
|
let next = NEXT[screen];
|
|
55679
56367
|
while (next && (skipsCustomBranch(next, preset) || skipsBranchPolicy(next, basePath) || skipsYoutrack(next, tracker) || skipsBasePath(next, basePath)))
|
|
@@ -55756,6 +56444,7 @@ function createInitialDraft(config = readConfig(), opts = {}) {
|
|
|
55756
56444
|
branchPreset: config.branchPolicy.preset,
|
|
55757
56445
|
branchAllowed: policy.allowed.join(", "),
|
|
55758
56446
|
branchProtected: policy.protected.join(", "),
|
|
56447
|
+
commitPolicy: { ...config.commitPolicy },
|
|
55759
56448
|
baseUrl: "",
|
|
55760
56449
|
basePath: process.env.WORKFLOW_WORKSPACE_ROOT ?? "",
|
|
55761
56450
|
issueTracker: "youtrack",
|
|
@@ -55793,23 +56482,17 @@ function reducer3(draft, action) {
|
|
|
55793
56482
|
const next = decodeIssueTracker(action.value, draft.values.issueTracker);
|
|
55794
56483
|
if (next === draft.values.issueTracker)
|
|
55795
56484
|
return draft;
|
|
55796
|
-
const stripIssues = (workspace) => {
|
|
55797
|
-
const rest = { ...workspace };
|
|
55798
|
-
delete rest.issues;
|
|
55799
|
-
return rest;
|
|
55800
|
-
};
|
|
55801
|
-
const needsStrip = next !== "github" && (draft.values.workspaces.some((w) => w.issues !== undefined) || draft.workspaceDraft?.issues !== undefined);
|
|
55802
56485
|
const errors = { ...draft.errors };
|
|
55803
56486
|
delete errors.baseUrl;
|
|
55804
56487
|
return {
|
|
55805
56488
|
...draft,
|
|
55806
56489
|
errors,
|
|
55807
|
-
workspaceDraft:
|
|
56490
|
+
workspaceDraft: draft.workspaceDraft,
|
|
55808
56491
|
values: {
|
|
55809
56492
|
...draft.values,
|
|
55810
56493
|
issueTracker: next,
|
|
55811
56494
|
baseUrl: next === "youtrack" ? draft.values.baseUrl : "",
|
|
55812
|
-
workspaces:
|
|
56495
|
+
workspaces: draft.values.workspaces
|
|
55813
56496
|
}
|
|
55814
56497
|
};
|
|
55815
56498
|
}
|
|
@@ -55939,6 +56622,18 @@ function reducer3(draft, action) {
|
|
|
55939
56622
|
errors: {}
|
|
55940
56623
|
};
|
|
55941
56624
|
}
|
|
56625
|
+
case "workspaceAdvancedOpen": {
|
|
56626
|
+
const entry = draft.values.workspaces[action.index];
|
|
56627
|
+
if (!entry)
|
|
56628
|
+
return draft;
|
|
56629
|
+
return {
|
|
56630
|
+
...draft,
|
|
56631
|
+
screen: "workspaceAdvanced",
|
|
56632
|
+
workspaceIndex: action.index,
|
|
56633
|
+
workspaceDraft: entry.vcs ? { ...entry, vcs: { ...entry.vcs } } : { ...entry },
|
|
56634
|
+
workspaceEditorField: undefined
|
|
56635
|
+
};
|
|
56636
|
+
}
|
|
55942
56637
|
case "workspaceRemove":
|
|
55943
56638
|
return {
|
|
55944
56639
|
...draft,
|
|
@@ -55962,34 +56657,165 @@ function reducer3(draft, action) {
|
|
|
55962
56657
|
...draft,
|
|
55963
56658
|
workspaceDraft: {
|
|
55964
56659
|
...base,
|
|
55965
|
-
vcs: provider === "skip" ? undefined : {
|
|
56660
|
+
vcs: provider === "skip" ? undefined : { ...vcs, provider }
|
|
55966
56661
|
}
|
|
55967
56662
|
};
|
|
55968
56663
|
}
|
|
55969
|
-
case "
|
|
55970
|
-
|
|
55971
|
-
|
|
56664
|
+
case "workspaceAdvancedSelect":
|
|
56665
|
+
return { ...draft, screen: "workspaceAdvancedValue", workspaceEditorField: action.field };
|
|
56666
|
+
case "workspaceAdvancedSet": {
|
|
56667
|
+
if (!draft.workspaceDraft)
|
|
55972
56668
|
return draft;
|
|
55973
|
-
const entry = wd.vcs ? { ...wd, vcs: { ...wd.vcs } } : { ...wd, vcs: undefined };
|
|
55974
|
-
const workspaces = draft.workspaceIndex === null ? [...draft.values.workspaces, entry] : draft.values.workspaces.map((w, i) => i === draft.workspaceIndex ? entry : w);
|
|
55975
56669
|
return {
|
|
55976
56670
|
...draft,
|
|
55977
|
-
|
|
55978
|
-
|
|
55979
|
-
|
|
55980
|
-
|
|
55981
|
-
|
|
56671
|
+
workspaceDraft: setWorkspaceEditorValue(draft.workspaceDraft, action.field, action.value, {
|
|
56672
|
+
branchPreset: draft.values.branchPreset,
|
|
56673
|
+
commitPreset: draft.values.commitPolicy.preset
|
|
56674
|
+
}),
|
|
56675
|
+
screen: "workspaceAdvanced"
|
|
55982
56676
|
};
|
|
55983
56677
|
}
|
|
55984
|
-
|
|
55985
|
-
}
|
|
55986
|
-
|
|
55987
|
-
|
|
55988
|
-
|
|
55989
|
-
|
|
55990
|
-
|
|
55991
|
-
|
|
55992
|
-
|
|
56678
|
+
case "globalCommitOpen":
|
|
56679
|
+
return { ...draft, screen: "globalCommitPolicy" };
|
|
56680
|
+
case "globalCommitEditPattern":
|
|
56681
|
+
return { ...draft, screen: "globalCommitPattern" };
|
|
56682
|
+
case "globalCommitPreset": {
|
|
56683
|
+
const valid = [
|
|
56684
|
+
"conventional",
|
|
56685
|
+
"gitmoji",
|
|
56686
|
+
"ticket-prefix",
|
|
56687
|
+
"freeform",
|
|
56688
|
+
"custom",
|
|
56689
|
+
"auto"
|
|
56690
|
+
];
|
|
56691
|
+
if (!valid.includes(action.value))
|
|
56692
|
+
return draft;
|
|
56693
|
+
return {
|
|
56694
|
+
...draft,
|
|
56695
|
+
values: {
|
|
56696
|
+
...draft.values,
|
|
56697
|
+
commitPolicy: {
|
|
56698
|
+
...draft.values.commitPolicy,
|
|
56699
|
+
preset: action.value
|
|
56700
|
+
}
|
|
56701
|
+
}
|
|
56702
|
+
};
|
|
56703
|
+
}
|
|
56704
|
+
case "globalCommitPattern":
|
|
56705
|
+
return {
|
|
56706
|
+
...draft,
|
|
56707
|
+
values: {
|
|
56708
|
+
...draft.values,
|
|
56709
|
+
commitPolicy: { ...draft.values.commitPolicy, pattern: action.value || undefined }
|
|
56710
|
+
}
|
|
56711
|
+
};
|
|
56712
|
+
case "globalCommitPatternDone":
|
|
56713
|
+
return { ...draft, screen: "globalCommitPolicy" };
|
|
56714
|
+
case "workspaceProfileCreate": {
|
|
56715
|
+
const name = action.name.trim();
|
|
56716
|
+
if (!draft.workspaceDraft || !name || draft.workspaceDraft.profiles?.[name])
|
|
56717
|
+
return draft;
|
|
56718
|
+
const profiles = {
|
|
56719
|
+
...draft.workspaceDraft.profiles,
|
|
56720
|
+
[name]: { commitPolicy: { preset: "conventional" } }
|
|
56721
|
+
};
|
|
56722
|
+
return { ...draft, workspaceDraft: { ...draft.workspaceDraft, profiles } };
|
|
56723
|
+
}
|
|
56724
|
+
case "workspaceProfileDelete": {
|
|
56725
|
+
if (!draft.workspaceDraft?.profiles?.[action.name])
|
|
56726
|
+
return draft;
|
|
56727
|
+
const profiles = { ...draft.workspaceDraft.profiles };
|
|
56728
|
+
delete profiles[action.name];
|
|
56729
|
+
return {
|
|
56730
|
+
...draft,
|
|
56731
|
+
workspaceDraft: {
|
|
56732
|
+
...draft.workspaceDraft,
|
|
56733
|
+
profiles,
|
|
56734
|
+
defaultProfile: draft.workspaceDraft.defaultProfile === action.name ? undefined : draft.workspaceDraft.defaultProfile
|
|
56735
|
+
}
|
|
56736
|
+
};
|
|
56737
|
+
}
|
|
56738
|
+
case "workspaceProfileDefault": {
|
|
56739
|
+
if (!draft.workspaceDraft?.profiles?.[action.name])
|
|
56740
|
+
return draft;
|
|
56741
|
+
return { ...draft, workspaceDraft: { ...draft.workspaceDraft, defaultProfile: action.name } };
|
|
56742
|
+
}
|
|
56743
|
+
case "workspaceProfileSet": {
|
|
56744
|
+
const profile = draft.workspaceDraft?.profiles?.[action.name];
|
|
56745
|
+
if (!draft.workspaceDraft || !profile)
|
|
56746
|
+
return draft;
|
|
56747
|
+
return {
|
|
56748
|
+
...draft,
|
|
56749
|
+
workspaceDraft: {
|
|
56750
|
+
...draft.workspaceDraft,
|
|
56751
|
+
profiles: {
|
|
56752
|
+
...draft.workspaceDraft.profiles,
|
|
56753
|
+
[action.name]: setProfileEditorValue(profile, action.field, action.value, {
|
|
56754
|
+
branchPreset: draft.values.branchPreset,
|
|
56755
|
+
commitPreset: draft.values.commitPolicy.preset
|
|
56756
|
+
})
|
|
56757
|
+
}
|
|
56758
|
+
}
|
|
56759
|
+
};
|
|
56760
|
+
}
|
|
56761
|
+
case "workspaceTrackCreate": {
|
|
56762
|
+
const name = action.name.trim();
|
|
56763
|
+
if (!draft.workspaceDraft || !name || draft.workspaceDraft.releaseTracks?.[name])
|
|
56764
|
+
return draft;
|
|
56765
|
+
return {
|
|
56766
|
+
...draft,
|
|
56767
|
+
workspaceDraft: {
|
|
56768
|
+
...draft.workspaceDraft,
|
|
56769
|
+
releaseTracks: { ...draft.workspaceDraft.releaseTracks, [name]: createReleaseTrack() }
|
|
56770
|
+
}
|
|
56771
|
+
};
|
|
56772
|
+
}
|
|
56773
|
+
case "workspaceTrackDelete": {
|
|
56774
|
+
if (!draft.workspaceDraft?.releaseTracks?.[action.name])
|
|
56775
|
+
return draft;
|
|
56776
|
+
const releaseTracks = { ...draft.workspaceDraft.releaseTracks };
|
|
56777
|
+
delete releaseTracks[action.name];
|
|
56778
|
+
return { ...draft, workspaceDraft: { ...draft.workspaceDraft, releaseTracks } };
|
|
56779
|
+
}
|
|
56780
|
+
case "workspaceTrackSet": {
|
|
56781
|
+
const track = draft.workspaceDraft?.releaseTracks?.[action.name];
|
|
56782
|
+
if (!draft.workspaceDraft || !track)
|
|
56783
|
+
return draft;
|
|
56784
|
+
return {
|
|
56785
|
+
...draft,
|
|
56786
|
+
workspaceDraft: {
|
|
56787
|
+
...draft.workspaceDraft,
|
|
56788
|
+
releaseTracks: {
|
|
56789
|
+
...draft.workspaceDraft.releaseTracks,
|
|
56790
|
+
[action.name]: setTrackEditorValue(track, action.field, action.value)
|
|
56791
|
+
}
|
|
56792
|
+
}
|
|
56793
|
+
};
|
|
56794
|
+
}
|
|
56795
|
+
case "workspaceSave": {
|
|
56796
|
+
const wd = draft.workspaceDraft;
|
|
56797
|
+
if (!wd || !wd.name.trim() || !wd.glob.trim())
|
|
56798
|
+
return draft;
|
|
56799
|
+
const entry = wd.vcs ? { ...wd, vcs: { ...wd.vcs } } : { ...wd, vcs: undefined };
|
|
56800
|
+
const workspaces = draft.workspaceIndex === null ? [...draft.values.workspaces, entry] : draft.values.workspaces.map((w, i) => i === draft.workspaceIndex ? entry : w);
|
|
56801
|
+
return {
|
|
56802
|
+
...draft,
|
|
56803
|
+
screen: "workspaces",
|
|
56804
|
+
workspaceDraft: null,
|
|
56805
|
+
workspaceIndex: null,
|
|
56806
|
+
values: { ...draft.values, workspaces },
|
|
56807
|
+
errors: {}
|
|
56808
|
+
};
|
|
56809
|
+
}
|
|
56810
|
+
}
|
|
56811
|
+
}
|
|
56812
|
+
function defaultWorkspaceProvider(vcs, tracker) {
|
|
56813
|
+
if (tracker === "github")
|
|
56814
|
+
return "github";
|
|
56815
|
+
if (tracker === "gitlab")
|
|
56816
|
+
return "gitlab";
|
|
56817
|
+
return vcs === "gitlab" || vcs === "github" ? vcs : null;
|
|
56818
|
+
}
|
|
55993
56819
|
function workspaceVcs(vcs, tracker) {
|
|
55994
56820
|
const provider = defaultWorkspaceProvider(vcs, tracker);
|
|
55995
56821
|
return provider ? { provider } : undefined;
|
|
@@ -56018,32 +56844,30 @@ function workspaceDraftText(draft, field, value) {
|
|
|
56018
56844
|
}
|
|
56019
56845
|
|
|
56020
56846
|
// packages/workit-core/src/core/detect-hosts.ts
|
|
56021
|
-
import
|
|
56022
|
-
import os8 from "node:os";
|
|
56023
|
-
import path16 from "node:path";
|
|
56847
|
+
import os9 from "node:os";
|
|
56024
56848
|
|
|
56025
56849
|
// packages/workit-core/src/core/uninstall.ts
|
|
56026
|
-
import { existsSync as
|
|
56027
|
-
import
|
|
56028
|
-
import
|
|
56850
|
+
import { existsSync as existsSync13, readFileSync as readFileSync13, realpathSync as realpathSync3, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
56851
|
+
import os8 from "node:os";
|
|
56852
|
+
import path16 from "node:path";
|
|
56029
56853
|
var resolveUninstallPaths = (options = {}) => {
|
|
56030
|
-
const home = options.home ?? options.env?.HOME ??
|
|
56854
|
+
const home = options.home ?? options.env?.HOME ?? os8.homedir();
|
|
56031
56855
|
return {
|
|
56032
|
-
opencodeConfig: options.opencodeConfig ??
|
|
56033
|
-
cursorSettings: options.cursorSettings ??
|
|
56034
|
-
cursorMcp: options.cursorMcp ??
|
|
56035
|
-
cursorPluginDir: options.cursorPluginDir ??
|
|
56036
|
-
codexPluginDir:
|
|
56037
|
-
piConfig:
|
|
56856
|
+
opencodeConfig: options.opencodeConfig ?? path16.join(home, ".config", "opencode", "opencode.json"),
|
|
56857
|
+
cursorSettings: options.cursorSettings ?? path16.join(home, ".cursor", "settings.json"),
|
|
56858
|
+
cursorMcp: options.cursorMcp ?? path16.join(home, ".cursor", "mcp.json"),
|
|
56859
|
+
cursorPluginDir: options.cursorPluginDir ?? path16.join(home, ".cursor", "plugins", "local", "workit"),
|
|
56860
|
+
codexPluginDir: path16.join(home, ".codex", "plugins", "workit"),
|
|
56861
|
+
piConfig: path16.join(home, ".pi", "config.json")
|
|
56038
56862
|
};
|
|
56039
56863
|
};
|
|
56040
56864
|
var isRecord3 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
56041
56865
|
var readJsonRecord = (file) => {
|
|
56042
56866
|
let raw;
|
|
56043
56867
|
try {
|
|
56044
|
-
raw =
|
|
56868
|
+
raw = readFileSync13(file, "utf8");
|
|
56045
56869
|
} catch {
|
|
56046
|
-
if (
|
|
56870
|
+
if (existsSync13(file))
|
|
56047
56871
|
return { kind: "malformed", error: `${file} is not readable` };
|
|
56048
56872
|
return { kind: "missing" };
|
|
56049
56873
|
}
|
|
@@ -56055,8 +56879,8 @@ var readJsonRecord = (file) => {
|
|
|
56055
56879
|
}
|
|
56056
56880
|
};
|
|
56057
56881
|
var stripTrailingSep = (p) => {
|
|
56058
|
-
const j =
|
|
56059
|
-
return
|
|
56882
|
+
const j = path16.join(p);
|
|
56883
|
+
return path16.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
|
|
56060
56884
|
};
|
|
56061
56885
|
var CURSOR_LEGACY_IDENTITIES = ["workflow-toolkit", "local/workflow-toolkit"];
|
|
56062
56886
|
function cleanCursorSettings(settings, pluginDir) {
|
|
@@ -56167,7 +56991,7 @@ function planUninstall(paths = {}) {
|
|
|
56167
56991
|
const mcpExisting = readJsonRecord(res.cursorMcp);
|
|
56168
56992
|
const settingsDirty = settingsExisting.kind === "malformed" || settingsExisting.kind === "record" && cleanCursorSettings(settingsExisting.value, res.cursorPluginDir).changed;
|
|
56169
56993
|
const mcpDirty = mcpExisting.kind === "malformed" || mcpExisting.kind === "record" && cleanCursorMcp(mcpExisting.value).changed;
|
|
56170
|
-
const dirExists =
|
|
56994
|
+
const dirExists = existsSync13(res.cursorPluginDir);
|
|
56171
56995
|
const actions = [];
|
|
56172
56996
|
if (settingsDirty) {
|
|
56173
56997
|
actions.push({
|
|
@@ -56195,7 +57019,7 @@ function planUninstall(paths = {}) {
|
|
|
56195
57019
|
installed: settingsDirty || mcpDirty || dirExists,
|
|
56196
57020
|
actions
|
|
56197
57021
|
};
|
|
56198
|
-
const codexInstalled =
|
|
57022
|
+
const codexInstalled = existsSync13(res.codexPluginDir);
|
|
56199
57023
|
const codex = {
|
|
56200
57024
|
host: "codex",
|
|
56201
57025
|
installed: codexInstalled,
|
|
@@ -56217,8 +57041,8 @@ function planUninstall(paths = {}) {
|
|
|
56217
57041
|
return { hosts: [opencode, cursor, codex, pi] };
|
|
56218
57042
|
}
|
|
56219
57043
|
var canonicalRemoveDirAllowed = (actionPath, res) => {
|
|
56220
|
-
const expected =
|
|
56221
|
-
if (!(actionPath === expected &&
|
|
57044
|
+
const expected = path16.resolve(res.cursorPluginDir);
|
|
57045
|
+
if (!(actionPath === expected && path16.basename(expected) === "workit" && path16.basename(path16.dirname(expected)) === "local" && path16.basename(path16.dirname(path16.dirname(expected))) === "plugins")) {
|
|
56222
57046
|
return false;
|
|
56223
57047
|
}
|
|
56224
57048
|
try {
|
|
@@ -56242,7 +57066,7 @@ var applyEditJsonRemove = (target, cleaner) => {
|
|
|
56242
57066
|
`;
|
|
56243
57067
|
let current;
|
|
56244
57068
|
try {
|
|
56245
|
-
current =
|
|
57069
|
+
current = readFileSync13(target, "utf8");
|
|
56246
57070
|
} catch (error) {
|
|
56247
57071
|
return {
|
|
56248
57072
|
status: "failed",
|
|
@@ -56270,12 +57094,12 @@ function applyUninstall(plan, paths = {}) {
|
|
|
56270
57094
|
let status;
|
|
56271
57095
|
let detail;
|
|
56272
57096
|
if (action.kind === "remove-dir") {
|
|
56273
|
-
const resolved =
|
|
56274
|
-
const allowed = canonicalRemoveDirAllowed(resolved, res) || resolved ===
|
|
57097
|
+
const resolved = path16.resolve(action.path);
|
|
57098
|
+
const allowed = canonicalRemoveDirAllowed(resolved, res) || resolved === path16.resolve(res.codexPluginDir) && path16.basename(resolved) === "workit" && path16.basename(path16.dirname(resolved)) === "plugins";
|
|
56275
57099
|
if (!allowed) {
|
|
56276
57100
|
status = "failed";
|
|
56277
57101
|
detail = `refusing to remove non-canonical plugin directory: ${resolved}`;
|
|
56278
|
-
} else if (!
|
|
57102
|
+
} else if (!existsSync13(resolved)) {
|
|
56279
57103
|
status = "skipped";
|
|
56280
57104
|
detail = "directory already absent";
|
|
56281
57105
|
} else {
|
|
@@ -56306,13 +57130,7 @@ function applyUninstall(plan, paths = {}) {
|
|
|
56306
57130
|
|
|
56307
57131
|
// packages/workit-core/src/core/detect-hosts.ts
|
|
56308
57132
|
var HOSTS = ["opencode", "cursor", "codex", "pi"];
|
|
56309
|
-
var
|
|
56310
|
-
opencode: [path16.join(".config", "opencode")],
|
|
56311
|
-
cursor: [".cursor"],
|
|
56312
|
-
codex: [".codex"],
|
|
56313
|
-
pi: [".pi"]
|
|
56314
|
-
};
|
|
56315
|
-
var WIZARD_HOSTS = ["opencode", "cursor"];
|
|
57133
|
+
var WIZARD_HOSTS = [...HOSTS];
|
|
56316
57134
|
function preselectedPlatforms(detection) {
|
|
56317
57135
|
return WIZARD_HOSTS.filter((host) => detection[host].detected);
|
|
56318
57136
|
}
|
|
@@ -56326,52 +57144,19 @@ function emptyDetection() {
|
|
|
56326
57144
|
}
|
|
56327
57145
|
function detectHosts(options = {}) {
|
|
56328
57146
|
const env = options.env ?? process.env;
|
|
56329
|
-
const home = options.home ?? env.HOME ??
|
|
56330
|
-
const plan = planUninstall(options);
|
|
57147
|
+
const home = options.home ?? env.HOME ?? os9.homedir();
|
|
57148
|
+
const plan = planUninstall({ ...options, home, env });
|
|
56331
57149
|
const configuredByHost = new Map(plan.hosts.map((h) => [h.host, h.installed]));
|
|
56332
57150
|
const found = emptyDetection();
|
|
56333
57151
|
for (const host of HOSTS) {
|
|
56334
|
-
const detected =
|
|
57152
|
+
const detected = findHostExecutable(host, { home, env }) !== null || installedHostApp(host, home, env);
|
|
56335
57153
|
found[host] = {
|
|
56336
57154
|
detected,
|
|
56337
|
-
configured:
|
|
57155
|
+
configured: host === "codex" ? isCodexWorkitInstalled(home, env) || (configuredByHost.get(host) ?? false) : host === "pi" ? isPiWorkitInstalled(home, env) || (configuredByHost.get(host) ?? false) : configuredByHost.get(host) ?? false
|
|
56338
57156
|
};
|
|
56339
57157
|
}
|
|
56340
57158
|
return found;
|
|
56341
57159
|
}
|
|
56342
|
-
function cliFound(name, env, home) {
|
|
56343
|
-
if (commandOnPath(name, env))
|
|
56344
|
-
return true;
|
|
56345
|
-
const extra = managerBinDirs(home);
|
|
56346
|
-
if (extra.length === 0)
|
|
56347
|
-
return false;
|
|
56348
|
-
return commandOnPath(name, {
|
|
56349
|
-
...env,
|
|
56350
|
-
PATH: [...(env.PATH ?? "").split(path16.delimiter), ...extra].join(path16.delimiter)
|
|
56351
|
-
});
|
|
56352
|
-
}
|
|
56353
|
-
var managerBinDirs = (home) => {
|
|
56354
|
-
const dirs = [path16.join(home, ".local", "bin"), path16.join(home, ".asdf", "shims")];
|
|
56355
|
-
const versioned = [
|
|
56356
|
-
[path16.join(home, ".local", "share", "fnm", "node-versions"), path16.join("installation", "bin")],
|
|
56357
|
-
[path16.join(home, ".nvm", "versions", "node"), "bin"]
|
|
56358
|
-
];
|
|
56359
|
-
for (const [base, tail] of versioned) {
|
|
56360
|
-
let entries;
|
|
56361
|
-
try {
|
|
56362
|
-
entries = readdirSync5(base, { withFileTypes: true });
|
|
56363
|
-
} catch {
|
|
56364
|
-
continue;
|
|
56365
|
-
}
|
|
56366
|
-
for (const entry of entries) {
|
|
56367
|
-
try {
|
|
56368
|
-
if (entry.isDirectory())
|
|
56369
|
-
dirs.push(path16.join(base, entry.name, tail));
|
|
56370
|
-
} catch {}
|
|
56371
|
-
}
|
|
56372
|
-
}
|
|
56373
|
-
return dirs;
|
|
56374
|
-
};
|
|
56375
57160
|
|
|
56376
57161
|
// packages/workit-cli/src/search-select.tsx
|
|
56377
57162
|
var import_react65 = __toESM(require_react(), 1);
|
|
@@ -56469,22 +57254,10 @@ function SearchSelect({
|
|
|
56469
57254
|
var jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
|
|
56470
57255
|
var PLATFORM_LABELS = [
|
|
56471
57256
|
{ label: "OpenCode", value: "opencode" },
|
|
56472
|
-
{ label: "Cursor", value: "cursor" }
|
|
57257
|
+
{ label: "Cursor", value: "cursor" },
|
|
57258
|
+
{ label: "Codex", value: "codex" },
|
|
57259
|
+
{ label: "Pi", value: "pi" }
|
|
56473
57260
|
];
|
|
56474
|
-
function platformOptions(detection) {
|
|
56475
|
-
return PLATFORM_LABELS.map(({ label, value }) => {
|
|
56476
|
-
const found = detection[value];
|
|
56477
|
-
const tag = found.configured ? " · already configured" : found.detected ? " · detected" : "";
|
|
56478
|
-
return { label: `${label}${tag}`, value };
|
|
56479
|
-
});
|
|
56480
|
-
}
|
|
56481
|
-
function externalHostGuidance(detection) {
|
|
56482
|
-
return ["codex", "pi"].map((host) => {
|
|
56483
|
-
const found = detection[host];
|
|
56484
|
-
const status = found.configured ? "already configured" : found.detected ? "detected" : "not detected";
|
|
56485
|
-
return host === "codex" ? `Codex · ${status} — plugin/hooks setup: https://github.com/BrainerVirus/workit#readme (Codex CLI / desktop)` : `Pi · ${status} — install separately: pi install @brainervirus/workit-pi`;
|
|
56486
|
-
});
|
|
56487
|
-
}
|
|
56488
57261
|
var BRANCH_PRESETS = [
|
|
56489
57262
|
{ label: "GitFlow", value: "gitflow" },
|
|
56490
57263
|
{ label: "GitHub Flow", value: "github-flow" },
|
|
@@ -56522,6 +57295,99 @@ var ISSUE_TRACKERS = [
|
|
|
56522
57295
|
{ label: "GitLab Issues", value: "gitlab" },
|
|
56523
57296
|
{ label: "None", value: "none" }
|
|
56524
57297
|
];
|
|
57298
|
+
var WORKSPACE_ADVANCED_FIELDS = [
|
|
57299
|
+
{ label: "Hosting provider account", value: "vcs.account" },
|
|
57300
|
+
{ label: "Default target branch", value: "vcs.defaultTargetBranch" },
|
|
57301
|
+
{ label: "Workspace YouTrack URL", value: "youtrack.baseUrl" },
|
|
57302
|
+
{ label: "Link issues in YouTrack", value: "youtrack.link_issues" },
|
|
57303
|
+
{ label: "Link GitHub issues on pull requests", value: "issues.link_on_pr" },
|
|
57304
|
+
{ label: "Branch preset", value: "branchPolicy.preset" },
|
|
57305
|
+
{ label: "Allowed branch patterns", value: "branchPolicy.allowed" },
|
|
57306
|
+
{ label: "Protected branches", value: "branchPolicy.protected" },
|
|
57307
|
+
{ label: "Develop branch", value: "branchPolicy.developBranch" },
|
|
57308
|
+
{ label: "Integration method (pr or merge)", value: "branchPolicy.integration" },
|
|
57309
|
+
{ label: "Feature prefix", value: "branchPolicy.prefixes.feature" },
|
|
57310
|
+
{ label: "Bugfix prefix", value: "branchPolicy.prefixes.bugfix" },
|
|
57311
|
+
{ label: "Release prefix", value: "branchPolicy.prefixes.release" },
|
|
57312
|
+
{ label: "Hotfix prefix", value: "branchPolicy.prefixes.hotfix" },
|
|
57313
|
+
{ label: "Commit policy preset", value: "commitPolicy.preset" },
|
|
57314
|
+
{ label: "Custom commit pattern", value: "commitPolicy.pattern" },
|
|
57315
|
+
{ label: "Default profile name", value: "defaultProfile" }
|
|
57316
|
+
];
|
|
57317
|
+
var PROFILE_FIELDS = [
|
|
57318
|
+
{ label: "Branch preset", value: "branchPolicy.preset" },
|
|
57319
|
+
{ label: "Allowed patterns", value: "branchPolicy.allowed" },
|
|
57320
|
+
{ label: "Protected branches", value: "branchPolicy.protected" },
|
|
57321
|
+
{ label: "Develop branch", value: "branchPolicy.developBranch" },
|
|
57322
|
+
{ label: "Integration (pr or merge)", value: "branchPolicy.integration" },
|
|
57323
|
+
{ label: "Feature prefix", value: "branchPolicy.prefixes.feature" },
|
|
57324
|
+
{ label: "Bugfix prefix", value: "branchPolicy.prefixes.bugfix" },
|
|
57325
|
+
{ label: "Release prefix", value: "branchPolicy.prefixes.release" },
|
|
57326
|
+
{ label: "Hotfix prefix", value: "branchPolicy.prefixes.hotfix" },
|
|
57327
|
+
{ label: "Commit preset", value: "commitPolicy.preset" },
|
|
57328
|
+
{ label: "Commit pattern", value: "commitPolicy.pattern" }
|
|
57329
|
+
];
|
|
57330
|
+
var TRACK_FIELDS = [
|
|
57331
|
+
{ label: "Strategy", value: "strategy" },
|
|
57332
|
+
{ label: "Production branch", value: "productionBranch" },
|
|
57333
|
+
{ label: "Integration branch", value: "integrationBranch" },
|
|
57334
|
+
{ label: "Feature branch naming", value: "naming.feature" },
|
|
57335
|
+
{ label: "Release branch naming", value: "naming.release" },
|
|
57336
|
+
{ label: "Hotfix branch naming", value: "naming.hotfix" },
|
|
57337
|
+
{ label: "Base branch", value: "baseBranch" },
|
|
57338
|
+
{ label: "Merge-back branches", value: "mergeBackBranches" },
|
|
57339
|
+
{ label: "Pull request target", value: "pullRequestTarget" },
|
|
57340
|
+
{ label: "Tag namespace", value: "tagNamespace" },
|
|
57341
|
+
{ label: "Version source (manual, git-tag, package-json)", value: "versionSource.kind" },
|
|
57342
|
+
{ label: "Package.json path", value: "versionSource.path" },
|
|
57343
|
+
{ label: "Package version field", value: "versionSource.field" },
|
|
57344
|
+
{ label: "Required checks", value: "requiredChecks" }
|
|
57345
|
+
];
|
|
57346
|
+
var enumFieldOptions = (field) => {
|
|
57347
|
+
if (field === "commitPolicy.preset")
|
|
57348
|
+
return [{ label: "Inherit global", value: "inherit" }, ...commitPresetOptions];
|
|
57349
|
+
if (field === "branchPolicy.preset")
|
|
57350
|
+
return [
|
|
57351
|
+
{ label: "Inherit global", value: "inherit" },
|
|
57352
|
+
{ label: "GitFlow", value: "gitflow" },
|
|
57353
|
+
{ label: "GitHub Flow", value: "github-flow" },
|
|
57354
|
+
{ label: "Trunk-based", value: "trunk-based" },
|
|
57355
|
+
{ label: "Custom", value: "custom" }
|
|
57356
|
+
];
|
|
57357
|
+
if (field === "strategy")
|
|
57358
|
+
return [
|
|
57359
|
+
{ label: "GitFlow", value: "gitflow" },
|
|
57360
|
+
{ label: "GitHub Flow", value: "github-flow" },
|
|
57361
|
+
{ label: "Trunk-based", value: "trunk-based" },
|
|
57362
|
+
{ label: "Custom", value: "custom" }
|
|
57363
|
+
];
|
|
57364
|
+
if (field.endsWith(".integration"))
|
|
57365
|
+
return [
|
|
57366
|
+
{ label: "Pull requests", value: "pr" },
|
|
57367
|
+
{ label: "Merge commits", value: "merge" }
|
|
57368
|
+
];
|
|
57369
|
+
if (field === "versionSource.kind")
|
|
57370
|
+
return [
|
|
57371
|
+
{ label: "Package.json", value: "package-json" },
|
|
57372
|
+
{ label: "Git tag", value: "git-tag" },
|
|
57373
|
+
{ label: "Manual", value: "manual" }
|
|
57374
|
+
];
|
|
57375
|
+
if (field === "youtrack.link_issues" || field === "issues.link_on_pr")
|
|
57376
|
+
return [
|
|
57377
|
+
{ label: "Inherit global behavior", value: "inherit" },
|
|
57378
|
+
{ label: "Enabled", value: "true" },
|
|
57379
|
+
{ label: "Disabled", value: "false" }
|
|
57380
|
+
];
|
|
57381
|
+
return null;
|
|
57382
|
+
};
|
|
57383
|
+
var commitPresetOptions = [
|
|
57384
|
+
{ label: "Conventional commits", value: "conventional" },
|
|
57385
|
+
{ label: "Gitmoji", value: "gitmoji" },
|
|
57386
|
+
{ label: "Ticket prefix", value: "ticket-prefix" },
|
|
57387
|
+
{ label: "Freeform", value: "freeform" },
|
|
57388
|
+
{ label: "Custom pattern", value: "custom" },
|
|
57389
|
+
{ label: "Auto-detect", value: "auto" }
|
|
57390
|
+
];
|
|
56525
57391
|
var TIMEZONE_FALLBACK = [
|
|
56526
57392
|
"UTC",
|
|
56527
57393
|
"America/New_York",
|
|
@@ -56560,6 +57426,8 @@ var TEXT_SCREENS = new Set([
|
|
|
56560
57426
|
"basePath",
|
|
56561
57427
|
"workspaceName",
|
|
56562
57428
|
"workspaceGlob",
|
|
57429
|
+
"workspaceAdvancedValue",
|
|
57430
|
+
"globalCommitPattern",
|
|
56563
57431
|
"branchPolicyDevelop"
|
|
56564
57432
|
]);
|
|
56565
57433
|
var SEARCH_SCREENS = new Set(["locale", "timezone"]);
|
|
@@ -56604,6 +57472,479 @@ function SelectList({
|
|
|
56604
57472
|
}, option.value, true, undefined, this))
|
|
56605
57473
|
}, undefined, false, undefined, this);
|
|
56606
57474
|
}
|
|
57475
|
+
function HostPicker({
|
|
57476
|
+
detection,
|
|
57477
|
+
selected,
|
|
57478
|
+
onChange,
|
|
57479
|
+
onSubmit
|
|
57480
|
+
}) {
|
|
57481
|
+
const available = PLATFORM_LABELS.filter(({ value }) => detection[value].detected).map(({ value }) => value);
|
|
57482
|
+
const options = [
|
|
57483
|
+
{ label: "Select all available", value: "__all" },
|
|
57484
|
+
{ label: "Clear all", value: "__none" },
|
|
57485
|
+
...PLATFORM_LABELS.map(({ label, value }) => ({ label, value }))
|
|
57486
|
+
];
|
|
57487
|
+
const [index, setIndex] = import_react66.useState(0);
|
|
57488
|
+
const indexRef = import_react66.useRef(index);
|
|
57489
|
+
const [chosen, setChosen] = import_react66.useState(selected);
|
|
57490
|
+
const chosenRef = import_react66.useRef(chosen);
|
|
57491
|
+
import_react66.useEffect(() => {
|
|
57492
|
+
indexRef.current = index;
|
|
57493
|
+
}, [index]);
|
|
57494
|
+
import_react66.useEffect(() => {
|
|
57495
|
+
chosenRef.current = chosen;
|
|
57496
|
+
}, [chosen]);
|
|
57497
|
+
const update = (next) => {
|
|
57498
|
+
chosenRef.current = next;
|
|
57499
|
+
setChosen(next);
|
|
57500
|
+
onChange(next);
|
|
57501
|
+
};
|
|
57502
|
+
use_input_default((input, key) => {
|
|
57503
|
+
if (key.upArrow || key.downArrow) {
|
|
57504
|
+
const next = Math.max(0, Math.min(options.length - 1, indexRef.current + (key.downArrow ? 1 : -1)));
|
|
57505
|
+
indexRef.current = next;
|
|
57506
|
+
setIndex(next);
|
|
57507
|
+
return;
|
|
57508
|
+
}
|
|
57509
|
+
if (input === " ") {
|
|
57510
|
+
const option = options[indexRef.current];
|
|
57511
|
+
if (option.value === "__all")
|
|
57512
|
+
update([...available]);
|
|
57513
|
+
else if (option.value === "__none")
|
|
57514
|
+
update([]);
|
|
57515
|
+
else if (detection[option.value].detected) {
|
|
57516
|
+
const next = chosenRef.current.includes(option.value) ? chosenRef.current.filter((host) => host !== option.value) : [...chosenRef.current, option.value];
|
|
57517
|
+
update(next);
|
|
57518
|
+
}
|
|
57519
|
+
} else if (key.return) {
|
|
57520
|
+
const option = options[indexRef.current];
|
|
57521
|
+
if (option.value === "__all")
|
|
57522
|
+
update([...available]);
|
|
57523
|
+
else if (option.value === "__none")
|
|
57524
|
+
update([]);
|
|
57525
|
+
onSubmit(chosenRef.current);
|
|
57526
|
+
}
|
|
57527
|
+
});
|
|
57528
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57529
|
+
flexDirection: "column",
|
|
57530
|
+
gap: 0,
|
|
57531
|
+
children: options.map((option, row) => {
|
|
57532
|
+
const host = option.value === "__all" || option.value === "__none" ? null : option.value;
|
|
57533
|
+
const detected = host === null || detection[host].detected;
|
|
57534
|
+
const checked = host !== null && chosen.includes(host);
|
|
57535
|
+
const label = host === null ? option.label : `${checked ? "[✓]" : "[ ]"} ${option.label}${detection[host].configured ? " · already configured" : detection[host].detected ? " · detected" : " · unavailable"}`;
|
|
57536
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57537
|
+
color: row === index ? "cyan" : undefined,
|
|
57538
|
+
dimColor: !detected,
|
|
57539
|
+
children: [
|
|
57540
|
+
row === index ? "❯ " : " ",
|
|
57541
|
+
label
|
|
57542
|
+
]
|
|
57543
|
+
}, option.value, true, undefined, this);
|
|
57544
|
+
})
|
|
57545
|
+
}, undefined, false, undefined, this);
|
|
57546
|
+
}
|
|
57547
|
+
function WorkspaceCollectionEditor({
|
|
57548
|
+
draft,
|
|
57549
|
+
dispatch
|
|
57550
|
+
}) {
|
|
57551
|
+
const [mode, setMode] = import_react66.useState("main");
|
|
57552
|
+
const [name, setName] = import_react66.useState("");
|
|
57553
|
+
const [field, setField] = import_react66.useState(null);
|
|
57554
|
+
const [nameError, setNameError] = import_react66.useState("");
|
|
57555
|
+
const workspace = draft.workspaceDraft;
|
|
57556
|
+
const profileNames = Object.keys(workspace?.profiles ?? {});
|
|
57557
|
+
const trackNames = Object.keys(workspace?.releaseTracks ?? {});
|
|
57558
|
+
if (!workspace)
|
|
57559
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57560
|
+
color: "red",
|
|
57561
|
+
children: "Workspace draft is unavailable."
|
|
57562
|
+
}, undefined, false, undefined, this);
|
|
57563
|
+
if (mode === "profiles") {
|
|
57564
|
+
const options = [
|
|
57565
|
+
...profileNames.flatMap((profile) => [
|
|
57566
|
+
{ label: `Edit profile ${profile}`, value: `edit:${profile}` },
|
|
57567
|
+
{ label: `Set ${profile} as default`, value: `default:${profile}` },
|
|
57568
|
+
{ label: `Delete profile ${profile}`, value: `delete:${profile}` }
|
|
57569
|
+
]),
|
|
57570
|
+
{ label: "Create profile", value: "create" },
|
|
57571
|
+
{ label: "Back to advanced settings", value: "back" }
|
|
57572
|
+
];
|
|
57573
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57574
|
+
flexDirection: "column",
|
|
57575
|
+
gap: 1,
|
|
57576
|
+
children: [
|
|
57577
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57578
|
+
bold: true,
|
|
57579
|
+
children: [
|
|
57580
|
+
"Profiles · default: ",
|
|
57581
|
+
workspace.defaultProfile ?? "none"
|
|
57582
|
+
]
|
|
57583
|
+
}, undefined, true, undefined, this),
|
|
57584
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57585
|
+
dimColor: true,
|
|
57586
|
+
children: "Profiles can override branch rules and commit conventions."
|
|
57587
|
+
}, undefined, false, undefined, this),
|
|
57588
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
57589
|
+
options,
|
|
57590
|
+
value: "back",
|
|
57591
|
+
onSelect: (value) => {
|
|
57592
|
+
const profileName = value.slice(value.indexOf(":") + 1);
|
|
57593
|
+
if (value === "create") {
|
|
57594
|
+
setNameError("");
|
|
57595
|
+
setName("");
|
|
57596
|
+
setMode("profileName");
|
|
57597
|
+
} else if (value.startsWith("edit:")) {
|
|
57598
|
+
setName(profileName);
|
|
57599
|
+
setMode("profileEdit");
|
|
57600
|
+
} else if (value.startsWith("default:"))
|
|
57601
|
+
dispatch({ type: "workspaceProfileDefault", name: profileName });
|
|
57602
|
+
else if (value.startsWith("delete:"))
|
|
57603
|
+
dispatch({ type: "workspaceProfileDelete", name: profileName });
|
|
57604
|
+
else
|
|
57605
|
+
setMode("main");
|
|
57606
|
+
}
|
|
57607
|
+
}, undefined, false, undefined, this)
|
|
57608
|
+
]
|
|
57609
|
+
}, undefined, true, undefined, this);
|
|
57610
|
+
}
|
|
57611
|
+
if (mode === "profileName")
|
|
57612
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57613
|
+
flexDirection: "column",
|
|
57614
|
+
gap: 1,
|
|
57615
|
+
children: [
|
|
57616
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57617
|
+
bold: true,
|
|
57618
|
+
children: "Create profile"
|
|
57619
|
+
}, undefined, false, undefined, this),
|
|
57620
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57621
|
+
dimColor: true,
|
|
57622
|
+
children: "Profile name:"
|
|
57623
|
+
}, undefined, false, undefined, this),
|
|
57624
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
57625
|
+
onSubmit: (value) => {
|
|
57626
|
+
const next = value.trim();
|
|
57627
|
+
if (!next) {
|
|
57628
|
+
setNameError("Enter a profile name.");
|
|
57629
|
+
return;
|
|
57630
|
+
}
|
|
57631
|
+
if (workspace.profiles?.[next]) {
|
|
57632
|
+
setNameError(`Profile ${next} already exists. Choose a different name or edit it from the list.`);
|
|
57633
|
+
return;
|
|
57634
|
+
}
|
|
57635
|
+
dispatch({ type: "workspaceProfileCreate", name: next });
|
|
57636
|
+
setName(next);
|
|
57637
|
+
setMode("profileEdit");
|
|
57638
|
+
}
|
|
57639
|
+
}, undefined, false, undefined, this),
|
|
57640
|
+
nameError && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57641
|
+
color: "red",
|
|
57642
|
+
children: nameError
|
|
57643
|
+
}, undefined, false, undefined, this),
|
|
57644
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57645
|
+
dimColor: true,
|
|
57646
|
+
children: "Enter to create · Esc Back"
|
|
57647
|
+
}, undefined, false, undefined, this)
|
|
57648
|
+
]
|
|
57649
|
+
}, undefined, true, undefined, this);
|
|
57650
|
+
if (mode === "profileEdit" || mode === "profileValue") {
|
|
57651
|
+
const selected = workspace.profiles?.[name];
|
|
57652
|
+
if (mode === "profileValue" && field) {
|
|
57653
|
+
const item = PROFILE_FIELDS.find((entry) => entry.value === field);
|
|
57654
|
+
const choices = enumFieldOptions(field);
|
|
57655
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57656
|
+
flexDirection: "column",
|
|
57657
|
+
gap: 1,
|
|
57658
|
+
children: [
|
|
57659
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57660
|
+
bold: true,
|
|
57661
|
+
children: [
|
|
57662
|
+
"Profile ",
|
|
57663
|
+
name,
|
|
57664
|
+
" · ",
|
|
57665
|
+
item?.label
|
|
57666
|
+
]
|
|
57667
|
+
}, undefined, true, undefined, this),
|
|
57668
|
+
choices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
57669
|
+
options: choices,
|
|
57670
|
+
value: selected ? profileEditorValue(selected, field) : choices[0].value,
|
|
57671
|
+
onSelect: (value) => {
|
|
57672
|
+
dispatch({
|
|
57673
|
+
type: "workspaceProfileSet",
|
|
57674
|
+
name,
|
|
57675
|
+
field,
|
|
57676
|
+
value
|
|
57677
|
+
});
|
|
57678
|
+
setMode("profileEdit");
|
|
57679
|
+
}
|
|
57680
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
57681
|
+
defaultValue: selected ? profileEditorValue(selected, field) : "",
|
|
57682
|
+
onSubmit: (value) => {
|
|
57683
|
+
dispatch({
|
|
57684
|
+
type: "workspaceProfileSet",
|
|
57685
|
+
name,
|
|
57686
|
+
field,
|
|
57687
|
+
value
|
|
57688
|
+
});
|
|
57689
|
+
setMode("profileEdit");
|
|
57690
|
+
}
|
|
57691
|
+
}, undefined, false, undefined, this),
|
|
57692
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57693
|
+
dimColor: true,
|
|
57694
|
+
children: "Enter to save · Esc Back"
|
|
57695
|
+
}, undefined, false, undefined, this)
|
|
57696
|
+
]
|
|
57697
|
+
}, undefined, true, undefined, this);
|
|
57698
|
+
}
|
|
57699
|
+
const options = [
|
|
57700
|
+
...PROFILE_FIELDS,
|
|
57701
|
+
{ label: "Done editing", value: "done" }
|
|
57702
|
+
];
|
|
57703
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57704
|
+
flexDirection: "column",
|
|
57705
|
+
gap: 1,
|
|
57706
|
+
children: [
|
|
57707
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57708
|
+
bold: true,
|
|
57709
|
+
children: [
|
|
57710
|
+
"Edit profile · ",
|
|
57711
|
+
name
|
|
57712
|
+
]
|
|
57713
|
+
}, undefined, true, undefined, this),
|
|
57714
|
+
PROFILE_FIELDS.map((item) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57715
|
+
dimColor: true,
|
|
57716
|
+
children: [
|
|
57717
|
+
item.label,
|
|
57718
|
+
": ",
|
|
57719
|
+
selected ? profileEditorValue(selected, item.value) || "unset" : ""
|
|
57720
|
+
]
|
|
57721
|
+
}, item.value, true, undefined, this)),
|
|
57722
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
57723
|
+
options,
|
|
57724
|
+
value: "done",
|
|
57725
|
+
onSelect: (value) => {
|
|
57726
|
+
if (value === "done")
|
|
57727
|
+
setMode("profiles");
|
|
57728
|
+
else {
|
|
57729
|
+
setField(value);
|
|
57730
|
+
setMode("profileValue");
|
|
57731
|
+
}
|
|
57732
|
+
}
|
|
57733
|
+
}, undefined, false, undefined, this)
|
|
57734
|
+
]
|
|
57735
|
+
}, undefined, true, undefined, this);
|
|
57736
|
+
}
|
|
57737
|
+
if (mode === "tracks") {
|
|
57738
|
+
const options = [
|
|
57739
|
+
...trackNames.flatMap((track) => [
|
|
57740
|
+
{ label: `Edit release track ${track}`, value: `edit:${track}` },
|
|
57741
|
+
{ label: `Delete release track ${track}`, value: `delete:${track}` }
|
|
57742
|
+
]),
|
|
57743
|
+
{ label: "Create release track", value: "create" },
|
|
57744
|
+
{ label: "Back to advanced settings", value: "back" }
|
|
57745
|
+
];
|
|
57746
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57747
|
+
flexDirection: "column",
|
|
57748
|
+
gap: 1,
|
|
57749
|
+
children: [
|
|
57750
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57751
|
+
bold: true,
|
|
57752
|
+
children: "Named release tracks"
|
|
57753
|
+
}, undefined, false, undefined, this),
|
|
57754
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57755
|
+
dimColor: true,
|
|
57756
|
+
children: "Each track has its own branches, naming, version source, and checks."
|
|
57757
|
+
}, undefined, false, undefined, this),
|
|
57758
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
57759
|
+
options,
|
|
57760
|
+
value: "back",
|
|
57761
|
+
onSelect: (value) => {
|
|
57762
|
+
const trackName = value.slice(value.indexOf(":") + 1);
|
|
57763
|
+
if (value === "create") {
|
|
57764
|
+
setNameError("");
|
|
57765
|
+
setName("");
|
|
57766
|
+
setMode("trackName");
|
|
57767
|
+
} else if (value.startsWith("edit:")) {
|
|
57768
|
+
setName(trackName);
|
|
57769
|
+
setMode("trackEdit");
|
|
57770
|
+
} else if (value.startsWith("delete:"))
|
|
57771
|
+
dispatch({ type: "workspaceTrackDelete", name: trackName });
|
|
57772
|
+
else
|
|
57773
|
+
setMode("main");
|
|
57774
|
+
}
|
|
57775
|
+
}, undefined, false, undefined, this)
|
|
57776
|
+
]
|
|
57777
|
+
}, undefined, true, undefined, this);
|
|
57778
|
+
}
|
|
57779
|
+
if (mode === "trackName")
|
|
57780
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57781
|
+
flexDirection: "column",
|
|
57782
|
+
gap: 1,
|
|
57783
|
+
children: [
|
|
57784
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57785
|
+
bold: true,
|
|
57786
|
+
children: "Create release track"
|
|
57787
|
+
}, undefined, false, undefined, this),
|
|
57788
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57789
|
+
dimColor: true,
|
|
57790
|
+
children: "Track name:"
|
|
57791
|
+
}, undefined, false, undefined, this),
|
|
57792
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
57793
|
+
onSubmit: (value) => {
|
|
57794
|
+
const next = value.trim();
|
|
57795
|
+
if (!next) {
|
|
57796
|
+
setNameError("Enter a release-track name.");
|
|
57797
|
+
return;
|
|
57798
|
+
}
|
|
57799
|
+
if (workspace.releaseTracks?.[next]) {
|
|
57800
|
+
setNameError(`Release track ${next} already exists. Choose a different name or edit it from the list.`);
|
|
57801
|
+
return;
|
|
57802
|
+
}
|
|
57803
|
+
dispatch({ type: "workspaceTrackCreate", name: next });
|
|
57804
|
+
setName(next);
|
|
57805
|
+
setMode("trackEdit");
|
|
57806
|
+
}
|
|
57807
|
+
}, undefined, false, undefined, this),
|
|
57808
|
+
nameError && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57809
|
+
color: "red",
|
|
57810
|
+
children: nameError
|
|
57811
|
+
}, undefined, false, undefined, this),
|
|
57812
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57813
|
+
dimColor: true,
|
|
57814
|
+
children: "Enter to create · Esc Back"
|
|
57815
|
+
}, undefined, false, undefined, this)
|
|
57816
|
+
]
|
|
57817
|
+
}, undefined, true, undefined, this);
|
|
57818
|
+
if (mode === "trackEdit" || mode === "trackValue") {
|
|
57819
|
+
const selected = workspace.releaseTracks?.[name];
|
|
57820
|
+
if (mode === "trackValue" && field) {
|
|
57821
|
+
const item = TRACK_FIELDS.find((entry) => entry.value === field);
|
|
57822
|
+
const choices = enumFieldOptions(field);
|
|
57823
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57824
|
+
flexDirection: "column",
|
|
57825
|
+
gap: 1,
|
|
57826
|
+
children: [
|
|
57827
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57828
|
+
bold: true,
|
|
57829
|
+
children: [
|
|
57830
|
+
"Release track ",
|
|
57831
|
+
name,
|
|
57832
|
+
" · ",
|
|
57833
|
+
item?.label
|
|
57834
|
+
]
|
|
57835
|
+
}, undefined, true, undefined, this),
|
|
57836
|
+
choices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
57837
|
+
options: choices,
|
|
57838
|
+
value: selected ? trackEditorValue(selected, field) : choices[0].value,
|
|
57839
|
+
onSelect: (value) => {
|
|
57840
|
+
dispatch({
|
|
57841
|
+
type: "workspaceTrackSet",
|
|
57842
|
+
name,
|
|
57843
|
+
field,
|
|
57844
|
+
value
|
|
57845
|
+
});
|
|
57846
|
+
setMode("trackEdit");
|
|
57847
|
+
}
|
|
57848
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
57849
|
+
defaultValue: selected ? trackEditorValue(selected, field) : "",
|
|
57850
|
+
onSubmit: (value) => {
|
|
57851
|
+
dispatch({
|
|
57852
|
+
type: "workspaceTrackSet",
|
|
57853
|
+
name,
|
|
57854
|
+
field,
|
|
57855
|
+
value
|
|
57856
|
+
});
|
|
57857
|
+
setMode("trackEdit");
|
|
57858
|
+
}
|
|
57859
|
+
}, undefined, false, undefined, this),
|
|
57860
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57861
|
+
dimColor: true,
|
|
57862
|
+
children: "Lists use comma-separated values · Enter to save · Esc Back"
|
|
57863
|
+
}, undefined, false, undefined, this)
|
|
57864
|
+
]
|
|
57865
|
+
}, undefined, true, undefined, this);
|
|
57866
|
+
}
|
|
57867
|
+
const options = [...TRACK_FIELDS, { label: "Done editing", value: "done" }];
|
|
57868
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57869
|
+
flexDirection: "column",
|
|
57870
|
+
gap: 1,
|
|
57871
|
+
children: [
|
|
57872
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57873
|
+
bold: true,
|
|
57874
|
+
children: [
|
|
57875
|
+
"Edit release track · ",
|
|
57876
|
+
name
|
|
57877
|
+
]
|
|
57878
|
+
}, undefined, true, undefined, this),
|
|
57879
|
+
TRACK_FIELDS.map((item) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57880
|
+
dimColor: true,
|
|
57881
|
+
children: [
|
|
57882
|
+
item.label,
|
|
57883
|
+
": ",
|
|
57884
|
+
selected ? trackEditorValue(selected, item.value) || "unset" : ""
|
|
57885
|
+
]
|
|
57886
|
+
}, item.value, true, undefined, this)),
|
|
57887
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
57888
|
+
options,
|
|
57889
|
+
value: "done",
|
|
57890
|
+
onSelect: (value) => {
|
|
57891
|
+
if (value === "done")
|
|
57892
|
+
setMode("tracks");
|
|
57893
|
+
else {
|
|
57894
|
+
setField(value);
|
|
57895
|
+
setMode("trackValue");
|
|
57896
|
+
}
|
|
57897
|
+
}
|
|
57898
|
+
}, undefined, false, undefined, this)
|
|
57899
|
+
]
|
|
57900
|
+
}, undefined, true, undefined, this);
|
|
57901
|
+
}
|
|
57902
|
+
const options = [
|
|
57903
|
+
...WORKSPACE_ADVANCED_FIELDS,
|
|
57904
|
+
{ label: "Manage profiles", value: "profiles" },
|
|
57905
|
+
{ label: "Manage release tracks", value: "tracks" },
|
|
57906
|
+
{ label: "Save workspace settings", value: "save" }
|
|
57907
|
+
];
|
|
57908
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57909
|
+
flexDirection: "column",
|
|
57910
|
+
gap: 1,
|
|
57911
|
+
children: [
|
|
57912
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57913
|
+
bold: true,
|
|
57914
|
+
children: [
|
|
57915
|
+
"Advanced workspace settings · ",
|
|
57916
|
+
workspace.name
|
|
57917
|
+
]
|
|
57918
|
+
}, undefined, true, undefined, this),
|
|
57919
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57920
|
+
dimColor: true,
|
|
57921
|
+
children: "Choose a setting to edit. Lists use comma-separated values; blank clears an override."
|
|
57922
|
+
}, undefined, false, undefined, this),
|
|
57923
|
+
[...WORKSPACE_ADVANCED_FIELDS].map(({ label, value }) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57924
|
+
dimColor: true,
|
|
57925
|
+
children: [
|
|
57926
|
+
label,
|
|
57927
|
+
": ",
|
|
57928
|
+
workspaceEditorValue(workspace, value) || "inherited / unset"
|
|
57929
|
+
]
|
|
57930
|
+
}, value, true, undefined, this)),
|
|
57931
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
57932
|
+
options,
|
|
57933
|
+
value: "save",
|
|
57934
|
+
onSelect: (value) => {
|
|
57935
|
+
if (value === "save")
|
|
57936
|
+
dispatch({ type: "workspaceSave" });
|
|
57937
|
+
else if (value === "profiles")
|
|
57938
|
+
setMode("profiles");
|
|
57939
|
+
else if (value === "tracks")
|
|
57940
|
+
setMode("tracks");
|
|
57941
|
+
else
|
|
57942
|
+
dispatch({ type: "workspaceAdvancedSelect", field: value });
|
|
57943
|
+
}
|
|
57944
|
+
}, undefined, false, undefined, this)
|
|
57945
|
+
]
|
|
57946
|
+
}, undefined, true, undefined, this);
|
|
57947
|
+
}
|
|
56607
57948
|
function effectivePolicy(values) {
|
|
56608
57949
|
return mergePreset(values.branchPreset, {
|
|
56609
57950
|
allowed: parseList(values.branchAllowed),
|
|
@@ -56815,6 +58156,8 @@ function describeMutation(m) {
|
|
|
56815
58156
|
return `+ register ${m.platform}: ${m.path}`;
|
|
56816
58157
|
case "install-adapter":
|
|
56817
58158
|
return `+ copy adapter ${m.platform}: ${m.path}`;
|
|
58159
|
+
case "install-host":
|
|
58160
|
+
return `+ install ${m.platform}: ${m.commands.map((command) => command.command).join(", ")}`;
|
|
56818
58161
|
case "set-token-path":
|
|
56819
58162
|
return `+ change ${m.key} in ${m.path} → ${m.value}`;
|
|
56820
58163
|
}
|
|
@@ -56870,28 +58213,21 @@ function Screen({
|
|
|
56870
58213
|
children: "Step 1 — Platforms"
|
|
56871
58214
|
}, undefined, false, undefined, this),
|
|
56872
58215
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
56873
|
-
children: "
|
|
58216
|
+
children: "Choose the detected tools where Workit should be configured."
|
|
56874
58217
|
}, undefined, false, undefined, this),
|
|
56875
58218
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
56876
58219
|
dimColor: true,
|
|
56877
|
-
children: "
|
|
58220
|
+
children: "Use Space to toggle, or choose Select all available / Clear all."
|
|
56878
58221
|
}, undefined, false, undefined, this),
|
|
56879
|
-
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(
|
|
56880
|
-
|
|
56881
|
-
|
|
58222
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(HostPicker, {
|
|
58223
|
+
detection,
|
|
58224
|
+
selected: draft.values.platforms,
|
|
56882
58225
|
onChange: (values) => dispatch({ type: "set", field: "platforms", value: values }),
|
|
56883
58226
|
onSubmit: (values) => {
|
|
56884
58227
|
dispatch({ type: "set", field: "platforms", value: values });
|
|
56885
58228
|
dispatch({ type: "next" });
|
|
56886
58229
|
}
|
|
56887
58230
|
}, undefined, false, undefined, this),
|
|
56888
|
-
externalHostGuidance(detection).map((guidance) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
56889
|
-
children: guidance
|
|
56890
|
-
}, guidance, false, undefined, this)),
|
|
56891
|
-
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
56892
|
-
dimColor: true,
|
|
56893
|
-
children: "For legacy installations, use `workit cutover` to preview migration."
|
|
56894
|
-
}, undefined, false, undefined, this),
|
|
56895
58231
|
draft.errors.platforms && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
56896
58232
|
color: "red",
|
|
56897
58233
|
children: draft.errors.platforms
|
|
@@ -57260,7 +58596,12 @@ function Screen({
|
|
|
57260
58596
|
})),
|
|
57261
58597
|
{ label: "Add workspace", value: "add" },
|
|
57262
58598
|
{ label: `Use current project (${base})`, value: "current" },
|
|
57263
|
-
{ label: "Done", value: "done" }
|
|
58599
|
+
{ label: "Done", value: "done" },
|
|
58600
|
+
{ label: "Advanced global commit policy", value: "global-commit" },
|
|
58601
|
+
...draft.values.workspaces.map((w, i) => ({
|
|
58602
|
+
label: `Advanced settings for ${w.name}`,
|
|
58603
|
+
value: `advanced:${i}`
|
|
58604
|
+
}))
|
|
57264
58605
|
];
|
|
57265
58606
|
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57266
58607
|
flexDirection: "column",
|
|
@@ -57300,6 +58641,10 @@ function Screen({
|
|
|
57300
58641
|
dispatch({ type: "workspaceEdit", index: Number(value.slice(5)) });
|
|
57301
58642
|
else if (value.startsWith("remove:"))
|
|
57302
58643
|
dispatch({ type: "workspaceRemove", index: Number(value.slice(7)) });
|
|
58644
|
+
else if (value.startsWith("advanced:"))
|
|
58645
|
+
dispatch({ type: "workspaceAdvancedOpen", index: Number(value.slice(9)) });
|
|
58646
|
+
else if (value === "global-commit")
|
|
58647
|
+
dispatch({ type: "globalCommitOpen" });
|
|
57303
58648
|
else if (value === "add")
|
|
57304
58649
|
dispatch({ type: "workspaceAdd" });
|
|
57305
58650
|
else if (value === "current")
|
|
@@ -57334,93 +58679,222 @@ function Screen({
|
|
|
57334
58679
|
onChange: (value) => dispatch({ type: "workspaceDraftName", value }),
|
|
57335
58680
|
onSubmit: () => dispatch({ type: "next" })
|
|
57336
58681
|
}, undefined, false, undefined, this),
|
|
57337
|
-
draft.errors.workspaceName && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57338
|
-
color: "red",
|
|
57339
|
-
children: draft.errors.workspaceName
|
|
58682
|
+
draft.errors.workspaceName && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58683
|
+
color: "red",
|
|
58684
|
+
children: draft.errors.workspaceName
|
|
58685
|
+
}, undefined, false, undefined, this),
|
|
58686
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58687
|
+
dimColor: true,
|
|
58688
|
+
children: "Enter to continue · Esc Back"
|
|
58689
|
+
}, undefined, false, undefined, this)
|
|
58690
|
+
]
|
|
58691
|
+
}, undefined, true, undefined, this);
|
|
58692
|
+
case "workspaceGlob": {
|
|
58693
|
+
const glob = draft.workspaceDraft?.glob ?? "";
|
|
58694
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
58695
|
+
flexDirection: "column",
|
|
58696
|
+
gap: 1,
|
|
58697
|
+
children: [
|
|
58698
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58699
|
+
bold: true,
|
|
58700
|
+
children: "Step 5 — Workspaces · Pattern"
|
|
58701
|
+
}, undefined, false, undefined, this),
|
|
58702
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58703
|
+
dimColor: true,
|
|
58704
|
+
children: "Workspace pattern (glob, e.g. /work/**):"
|
|
58705
|
+
}, undefined, false, undefined, this),
|
|
58706
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
58707
|
+
placeholder: SCREEN_PLACEHOLDERS.workspaceGlob,
|
|
58708
|
+
defaultValue: glob,
|
|
58709
|
+
onChange: (value) => dispatch({ type: "workspaceDraftGlob", value }),
|
|
58710
|
+
onSubmit: () => dispatch({ type: "next" })
|
|
58711
|
+
}, undefined, false, undefined, this),
|
|
58712
|
+
glob.trim() !== "" && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
58713
|
+
flexDirection: "column",
|
|
58714
|
+
gap: 0,
|
|
58715
|
+
children: [
|
|
58716
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58717
|
+
bold: true,
|
|
58718
|
+
children: "Match preview (shared matcher):"
|
|
58719
|
+
}, undefined, false, undefined, this),
|
|
58720
|
+
workspacePreviewTargets(resolveBasePath(draft.values)).map((target) => {
|
|
58721
|
+
const matches = matchWorkspace(glob, target);
|
|
58722
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58723
|
+
color: matches ? "green" : "red",
|
|
58724
|
+
children: [
|
|
58725
|
+
matches ? "✓ matches" : "✗ no match",
|
|
58726
|
+
" ",
|
|
58727
|
+
target
|
|
58728
|
+
]
|
|
58729
|
+
}, target, true, undefined, this);
|
|
58730
|
+
})
|
|
58731
|
+
]
|
|
58732
|
+
}, undefined, true, undefined, this),
|
|
58733
|
+
draft.errors.workspaceGlob && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58734
|
+
color: "red",
|
|
58735
|
+
children: draft.errors.workspaceGlob
|
|
58736
|
+
}, undefined, false, undefined, this),
|
|
58737
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58738
|
+
dimColor: true,
|
|
58739
|
+
children: "Enter to continue · Esc Back"
|
|
58740
|
+
}, undefined, false, undefined, this)
|
|
58741
|
+
]
|
|
58742
|
+
}, undefined, true, undefined, this);
|
|
58743
|
+
}
|
|
58744
|
+
case "workspaceProvider":
|
|
58745
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
58746
|
+
flexDirection: "column",
|
|
58747
|
+
gap: 1,
|
|
58748
|
+
children: [
|
|
58749
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58750
|
+
bold: true,
|
|
58751
|
+
children: "Step 5 — Workspaces · Provider"
|
|
58752
|
+
}, undefined, false, undefined, this),
|
|
58753
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58754
|
+
dimColor: true,
|
|
58755
|
+
children: "Version control provider for this workspace:"
|
|
58756
|
+
}, undefined, false, undefined, this),
|
|
58757
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
58758
|
+
options: VCS_PROVIDERS,
|
|
58759
|
+
value: draft.workspaceDraft?.vcs?.provider ?? "skip",
|
|
58760
|
+
onChange: (value) => dispatch({ type: "workspaceDraftProvider", value }),
|
|
58761
|
+
onSelect: (value) => {
|
|
58762
|
+
dispatch({ type: "workspaceDraftProvider", value });
|
|
58763
|
+
dispatch({ type: "workspaceSave" });
|
|
58764
|
+
}
|
|
58765
|
+
}, undefined, false, undefined, this),
|
|
58766
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58767
|
+
dimColor: true,
|
|
58768
|
+
children: "Enter to save · b Back · Esc Cancel"
|
|
58769
|
+
}, undefined, false, undefined, this)
|
|
58770
|
+
]
|
|
58771
|
+
}, undefined, true, undefined, this);
|
|
58772
|
+
case "workspaceAdvanced": {
|
|
58773
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(WorkspaceCollectionEditor, {
|
|
58774
|
+
draft,
|
|
58775
|
+
dispatch
|
|
58776
|
+
}, undefined, false, undefined, this);
|
|
58777
|
+
}
|
|
58778
|
+
case "workspaceAdvancedValue": {
|
|
58779
|
+
const field = draft.workspaceEditorField;
|
|
58780
|
+
const current = draft.workspaceDraft && field ? workspaceEditorValue(draft.workspaceDraft, field) : "";
|
|
58781
|
+
const label = WORKSPACE_ADVANCED_FIELDS.find((entry) => entry.value === field)?.label ?? "Setting";
|
|
58782
|
+
const choices = field ? enumFieldOptions(field) : null;
|
|
58783
|
+
const profileChoices = field === "defaultProfile" ? [
|
|
58784
|
+
{ label: "Inherit / no default profile", value: "" },
|
|
58785
|
+
...Object.keys(draft.workspaceDraft?.profiles ?? {}).map((name) => ({
|
|
58786
|
+
label: name,
|
|
58787
|
+
value: name
|
|
58788
|
+
}))
|
|
58789
|
+
] : null;
|
|
58790
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
58791
|
+
flexDirection: "column",
|
|
58792
|
+
gap: 1,
|
|
58793
|
+
children: [
|
|
58794
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58795
|
+
bold: true,
|
|
58796
|
+
children: [
|
|
58797
|
+
"Advanced workspace settings · ",
|
|
58798
|
+
label
|
|
58799
|
+
]
|
|
58800
|
+
}, undefined, true, undefined, this),
|
|
58801
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58802
|
+
dimColor: true,
|
|
58803
|
+
children: "Leave empty to clear this override. Use comma-separated values for lists."
|
|
58804
|
+
}, undefined, false, undefined, this),
|
|
58805
|
+
profileChoices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
58806
|
+
options: profileChoices,
|
|
58807
|
+
value: current,
|
|
58808
|
+
onSelect: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
|
|
58809
|
+
}, undefined, false, undefined, this) : choices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
58810
|
+
options: choices,
|
|
58811
|
+
value: current || choices[0].value,
|
|
58812
|
+
onSelect: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
|
|
58813
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
58814
|
+
defaultValue: current,
|
|
58815
|
+
onSubmit: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
|
|
58816
|
+
}, undefined, false, undefined, this),
|
|
58817
|
+
field?.endsWith("integration") && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58818
|
+
dimColor: true,
|
|
58819
|
+
children: "Enter pr or merge."
|
|
57340
58820
|
}, undefined, false, undefined, this),
|
|
57341
58821
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57342
58822
|
dimColor: true,
|
|
57343
|
-
children: "Enter to
|
|
58823
|
+
children: "Enter to save · Esc Back"
|
|
57344
58824
|
}, undefined, false, undefined, this)
|
|
57345
58825
|
]
|
|
57346
58826
|
}, undefined, true, undefined, this);
|
|
57347
|
-
|
|
57348
|
-
|
|
58827
|
+
}
|
|
58828
|
+
case "globalCommitPolicy": {
|
|
58829
|
+
const options = [
|
|
58830
|
+
{ label: "Conventional commits", value: "conventional" },
|
|
58831
|
+
{ label: "Gitmoji", value: "gitmoji" },
|
|
58832
|
+
{ label: "Ticket prefix", value: "ticket-prefix" },
|
|
58833
|
+
{ label: "Freeform", value: "freeform" },
|
|
58834
|
+
{ label: "Custom pattern", value: "custom" },
|
|
58835
|
+
{ label: "Auto-detect", value: "auto" },
|
|
58836
|
+
{ label: "Edit custom pattern…", value: "pattern" },
|
|
58837
|
+
{ label: "Done", value: "done" }
|
|
58838
|
+
];
|
|
57349
58839
|
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57350
58840
|
flexDirection: "column",
|
|
57351
58841
|
gap: 1,
|
|
57352
58842
|
children: [
|
|
57353
58843
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57354
58844
|
bold: true,
|
|
57355
|
-
children: "
|
|
58845
|
+
children: "Advanced global commit policy"
|
|
57356
58846
|
}, undefined, false, undefined, this),
|
|
57357
58847
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57358
58848
|
dimColor: true,
|
|
57359
|
-
children: "
|
|
58849
|
+
children: "Default convention used when a workspace has no commit override."
|
|
57360
58850
|
}, undefined, false, undefined, this),
|
|
57361
|
-
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(
|
|
57362
|
-
|
|
57363
|
-
defaultValue: glob,
|
|
57364
|
-
onChange: (value) => dispatch({ type: "workspaceDraftGlob", value }),
|
|
57365
|
-
onSubmit: () => dispatch({ type: "next" })
|
|
57366
|
-
}, undefined, false, undefined, this),
|
|
57367
|
-
glob.trim() !== "" && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57368
|
-
flexDirection: "column",
|
|
57369
|
-
gap: 0,
|
|
58851
|
+
draft.values.commitPolicy.pattern && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
58852
|
+
dimColor: true,
|
|
57370
58853
|
children: [
|
|
57371
|
-
|
|
57372
|
-
|
|
57373
|
-
children: "Match preview (shared matcher):"
|
|
57374
|
-
}, undefined, false, undefined, this),
|
|
57375
|
-
workspacePreviewTargets(resolveBasePath(draft.values)).map((target) => {
|
|
57376
|
-
const matches = matchWorkspace(glob, target);
|
|
57377
|
-
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57378
|
-
color: matches ? "green" : "red",
|
|
57379
|
-
children: [
|
|
57380
|
-
matches ? "✓ matches" : "✗ no match",
|
|
57381
|
-
" ",
|
|
57382
|
-
target
|
|
57383
|
-
]
|
|
57384
|
-
}, target, true, undefined, this);
|
|
57385
|
-
})
|
|
58854
|
+
"Custom pattern: ",
|
|
58855
|
+
draft.values.commitPolicy.pattern
|
|
57386
58856
|
]
|
|
57387
58857
|
}, undefined, true, undefined, this),
|
|
57388
|
-
|
|
57389
|
-
|
|
57390
|
-
|
|
58858
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
58859
|
+
options,
|
|
58860
|
+
value: draft.values.commitPolicy.preset,
|
|
58861
|
+
onSelect: (value) => {
|
|
58862
|
+
if (value === "pattern")
|
|
58863
|
+
dispatch({ type: "globalCommitEditPattern" });
|
|
58864
|
+
else if (value === "done")
|
|
58865
|
+
dispatch({ type: "back" });
|
|
58866
|
+
else
|
|
58867
|
+
dispatch({ type: "globalCommitPreset", value });
|
|
58868
|
+
}
|
|
57391
58869
|
}, undefined, false, undefined, this),
|
|
57392
58870
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57393
58871
|
dimColor: true,
|
|
57394
|
-
children: "Enter to
|
|
58872
|
+
children: "Enter to select · b Back"
|
|
57395
58873
|
}, undefined, false, undefined, this)
|
|
57396
58874
|
]
|
|
57397
58875
|
}, undefined, true, undefined, this);
|
|
57398
58876
|
}
|
|
57399
|
-
case "
|
|
58877
|
+
case "globalCommitPattern":
|
|
57400
58878
|
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57401
58879
|
flexDirection: "column",
|
|
57402
58880
|
gap: 1,
|
|
57403
58881
|
children: [
|
|
57404
58882
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57405
58883
|
bold: true,
|
|
57406
|
-
children: "
|
|
58884
|
+
children: "Advanced global commit policy · Custom pattern"
|
|
57407
58885
|
}, undefined, false, undefined, this),
|
|
57408
58886
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57409
58887
|
dimColor: true,
|
|
57410
|
-
children: "
|
|
58888
|
+
children: "Regular expression matched against the commit subject line."
|
|
57411
58889
|
}, undefined, false, undefined, this),
|
|
57412
|
-
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(
|
|
57413
|
-
|
|
57414
|
-
|
|
57415
|
-
|
|
57416
|
-
onSelect: (value) => {
|
|
57417
|
-
dispatch({ type: "workspaceDraftProvider", value });
|
|
57418
|
-
dispatch({ type: "workspaceSave" });
|
|
57419
|
-
}
|
|
58890
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
58891
|
+
defaultValue: draft.values.commitPolicy.pattern ?? "",
|
|
58892
|
+
onChange: (value) => dispatch({ type: "globalCommitPattern", value }),
|
|
58893
|
+
onSubmit: () => dispatch({ type: "globalCommitPatternDone" })
|
|
57420
58894
|
}, undefined, false, undefined, this),
|
|
57421
58895
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57422
58896
|
dimColor: true,
|
|
57423
|
-
children: "Enter to save ·
|
|
58897
|
+
children: "Enter to save · Esc Back"
|
|
57424
58898
|
}, undefined, false, undefined, this)
|
|
57425
58899
|
]
|
|
57426
58900
|
}, undefined, true, undefined, this);
|
|
@@ -57494,6 +58968,36 @@ function Screen({
|
|
|
57494
58968
|
case "summary": {
|
|
57495
58969
|
const policy = effectivePolicy(draft.values);
|
|
57496
58970
|
const preview = buildSetupPreview(draft.values, { cwd: resolveBasePath(draft.values) });
|
|
58971
|
+
const policyPreview = (() => {
|
|
58972
|
+
try {
|
|
58973
|
+
const current = readConfig();
|
|
58974
|
+
const config = {
|
|
58975
|
+
...current,
|
|
58976
|
+
branchPolicy: mergePreset(draft.values.branchPreset, {
|
|
58977
|
+
allowed: parseList(draft.values.branchAllowed),
|
|
58978
|
+
protectedNames: parseList(draft.values.branchProtected)
|
|
58979
|
+
}, current),
|
|
58980
|
+
commitPolicy: draft.values.commitPolicy
|
|
58981
|
+
};
|
|
58982
|
+
const checkout = resolveBasePath(draft.values);
|
|
58983
|
+
const workspace = resolveWorkspaceFromEntries(checkout, draft.values.workspaces);
|
|
58984
|
+
const resolved = resolveWorkspacePolicy(config, workspace);
|
|
58985
|
+
if (resolved.status === "invalid")
|
|
58986
|
+
return { error: resolved.error };
|
|
58987
|
+
return {
|
|
58988
|
+
error: null,
|
|
58989
|
+
workspace: workspace?.name ?? null,
|
|
58990
|
+
branchSource: resolved.provenance.branchPolicy,
|
|
58991
|
+
commitSource: resolved.provenance.commitPolicy,
|
|
58992
|
+
target: resolved.branchPolicy.defaultTargetBranch,
|
|
58993
|
+
branchPreset: resolved.branchPolicy.preset,
|
|
58994
|
+
commitPreset: resolved.commitPolicy.preset
|
|
58995
|
+
};
|
|
58996
|
+
} catch (error) {
|
|
58997
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
58998
|
+
}
|
|
58999
|
+
})();
|
|
59000
|
+
const canApply = preview.ok && policyPreview.error === null;
|
|
57497
59001
|
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57498
59002
|
flexDirection: "column",
|
|
57499
59003
|
gap: 1,
|
|
@@ -57544,6 +59048,52 @@ function Screen({
|
|
|
57544
59048
|
policy.protected.join(", ")
|
|
57545
59049
|
]
|
|
57546
59050
|
}, undefined, true, undefined, this),
|
|
59051
|
+
policyPreview.error === null ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
59052
|
+
flexDirection: "column",
|
|
59053
|
+
gap: 0,
|
|
59054
|
+
children: [
|
|
59055
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59056
|
+
children: [
|
|
59057
|
+
"Sample checkout: ",
|
|
59058
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59059
|
+
color: "green",
|
|
59060
|
+
children: resolveBasePath(draft.values)
|
|
59061
|
+
}, undefined, false, undefined, this),
|
|
59062
|
+
policyPreview.workspace ? ` · workspace ${policyPreview.workspace}` : " · no matching workspace"
|
|
59063
|
+
]
|
|
59064
|
+
}, undefined, true, undefined, this),
|
|
59065
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59066
|
+
children: [
|
|
59067
|
+
"Effective branch policy: ",
|
|
59068
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59069
|
+
color: "green",
|
|
59070
|
+
children: policyPreview.branchPreset
|
|
59071
|
+
}, undefined, false, undefined, this),
|
|
59072
|
+
" · target ",
|
|
59073
|
+
policyPreview.target,
|
|
59074
|
+
" · source ",
|
|
59075
|
+
policyPreview.branchSource
|
|
59076
|
+
]
|
|
59077
|
+
}, undefined, true, undefined, this),
|
|
59078
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59079
|
+
children: [
|
|
59080
|
+
"Effective commit policy: ",
|
|
59081
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59082
|
+
color: "green",
|
|
59083
|
+
children: policyPreview.commitPreset
|
|
59084
|
+
}, undefined, false, undefined, this),
|
|
59085
|
+
" · source ",
|
|
59086
|
+
policyPreview.commitSource
|
|
59087
|
+
]
|
|
59088
|
+
}, undefined, true, undefined, this)
|
|
59089
|
+
]
|
|
59090
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59091
|
+
color: "red",
|
|
59092
|
+
children: [
|
|
59093
|
+
"Policy preview failed: ",
|
|
59094
|
+
policyPreview.error
|
|
59095
|
+
]
|
|
59096
|
+
}, undefined, true, undefined, this),
|
|
57547
59097
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57548
59098
|
children: [
|
|
57549
59099
|
"YouTrack base URL:",
|
|
@@ -57592,7 +59142,7 @@ function Screen({
|
|
|
57592
59142
|
}, o.envKey, true, undefined, this))
|
|
57593
59143
|
]
|
|
57594
59144
|
}, undefined, true, undefined, this),
|
|
57595
|
-
|
|
59145
|
+
canApply ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
57596
59146
|
flexDirection: "column",
|
|
57597
59147
|
gap: 0,
|
|
57598
59148
|
children: [
|
|
@@ -57600,9 +59150,9 @@ function Screen({
|
|
|
57600
59150
|
bold: true,
|
|
57601
59151
|
children: "Will apply:"
|
|
57602
59152
|
}, undefined, false, undefined, this),
|
|
57603
|
-
preview.mutations.map((m) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
59153
|
+
preview.mutations.map((m, index) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57604
59154
|
children: describeMutation(m)
|
|
57605
|
-
}, `${m.type}:${
|
|
59155
|
+
}, `${m.type}:${index}`, false, undefined, this)),
|
|
57606
59156
|
preview.preserved.map((p) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57607
59157
|
color: "green",
|
|
57608
59158
|
children: [
|
|
@@ -57631,7 +59181,7 @@ function Screen({
|
|
|
57631
59181
|
}, undefined, false, undefined, this)
|
|
57632
59182
|
]
|
|
57633
59183
|
}, undefined, true, undefined, this),
|
|
57634
|
-
|
|
59184
|
+
canApply && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(ConfirmInput, {
|
|
57635
59185
|
defaultChoice: "confirm",
|
|
57636
59186
|
submitOnEnter: false,
|
|
57637
59187
|
onConfirm: () => dispatch({ type: "apply" }),
|
|
@@ -57639,7 +59189,7 @@ function Screen({
|
|
|
57639
59189
|
}, undefined, false, undefined, this),
|
|
57640
59190
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
57641
59191
|
dimColor: true,
|
|
57642
|
-
children:
|
|
59192
|
+
children: canApply ? "y to apply · b Back · Esc Cancel" : "b Back · Esc Cancel"
|
|
57643
59193
|
}, undefined, false, undefined, this)
|
|
57644
59194
|
]
|
|
57645
59195
|
}, undefined, true, undefined, this);
|
|
@@ -57658,7 +59208,7 @@ function Screen({
|
|
|
57658
59208
|
|
|
57659
59209
|
// packages/workit-core/src/core/logger.ts
|
|
57660
59210
|
import { appendFileSync, mkdirSync as mkdirSync6, readdirSync as readdirSync6, unlinkSync as unlinkSync4 } from "node:fs";
|
|
57661
|
-
import
|
|
59211
|
+
import os10 from "node:os";
|
|
57662
59212
|
import path17 from "node:path";
|
|
57663
59213
|
var REDACTED = "[REDACTED]";
|
|
57664
59214
|
var DEFAULT_MAX_RATE = 20;
|
|
@@ -57713,10 +59263,10 @@ var resolveStateDir = () => {
|
|
|
57713
59263
|
const override = process.env.WORKFLOW_TOOLKIT_STATE;
|
|
57714
59264
|
if (override)
|
|
57715
59265
|
return override;
|
|
57716
|
-
const home =
|
|
59266
|
+
const home = os10.homedir();
|
|
57717
59267
|
if (process.env.XDG_STATE_HOME)
|
|
57718
59268
|
return path17.join(process.env.XDG_STATE_HOME, "workit");
|
|
57719
|
-
switch (
|
|
59269
|
+
switch (os10.platform()) {
|
|
57720
59270
|
case "darwin":
|
|
57721
59271
|
return path17.join(home, "Library", "Application Support", "workit");
|
|
57722
59272
|
case "win32":
|
|
@@ -57725,7 +59275,7 @@ var resolveStateDir = () => {
|
|
|
57725
59275
|
return path17.join(process.env.HOME ?? home, ".local", "state", "workit");
|
|
57726
59276
|
}
|
|
57727
59277
|
};
|
|
57728
|
-
var homePattern = new RegExp(`${escapeRegExp2(
|
|
59278
|
+
var homePattern = new RegExp(`${escapeRegExp2(os10.homedir())}(?=[/\\\\]|$)|\\$HOME(?=[/\\\\]|$)`, "g");
|
|
57729
59279
|
var applyPatterns = (value) => {
|
|
57730
59280
|
let out = value;
|
|
57731
59281
|
out = out.replace(SECRET_VALUE, REDACTED);
|
|
@@ -58115,11 +59665,11 @@ async function runCutoverCommand(argv, deps = {}) {
|
|
|
58115
59665
|
}
|
|
58116
59666
|
|
|
58117
59667
|
// packages/workit-cli/src/task.ts
|
|
58118
|
-
import { readFileSync as
|
|
59668
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
58119
59669
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
58120
59670
|
|
|
58121
59671
|
// packages/workit-core/src/core.ts
|
|
58122
|
-
import { spawnSync as
|
|
59672
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
58123
59673
|
import { existsSync as existsSync17, realpathSync as realpathSync10 } from "node:fs";
|
|
58124
59674
|
import path27 from "node:path";
|
|
58125
59675
|
|
|
@@ -59792,7 +61342,7 @@ function assertProductWriteAllowed(input) {
|
|
|
59792
61342
|
// packages/workit-core/src/core/task-evaluation.ts
|
|
59793
61343
|
import { createHash as createHash10 } from "node:crypto";
|
|
59794
61344
|
import * as fs10 from "node:fs";
|
|
59795
|
-
import { spawnSync as
|
|
61345
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
59796
61346
|
import path25 from "node:path";
|
|
59797
61347
|
|
|
59798
61348
|
// packages/workit-core/src/core/authority.ts
|
|
@@ -59802,11 +61352,11 @@ import path24 from "node:path";
|
|
|
59802
61352
|
|
|
59803
61353
|
// packages/workit-core/src/core/auto-approval.ts
|
|
59804
61354
|
import { createHash as createHash8 } from "node:crypto";
|
|
59805
|
-
import { readFileSync as
|
|
61355
|
+
import { readFileSync as readFileSync16, realpathSync as realpathSync5 } from "node:fs";
|
|
59806
61356
|
import path23 from "node:path";
|
|
59807
61357
|
|
|
59808
61358
|
// packages/workit-core/src/core/branch.ts
|
|
59809
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as
|
|
61359
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync15, writeFileSync as writeFileSync8 } from "node:fs";
|
|
59810
61360
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
59811
61361
|
import { createHash as createHash7 } from "node:crypto";
|
|
59812
61362
|
import path22 from "node:path";
|
|
@@ -59911,11 +61461,11 @@ var gitContext = (workspaceRoot, paths = []) => {
|
|
|
59911
61461
|
// packages/workit-core/src/core/vcs-config.ts
|
|
59912
61462
|
import fs8 from "node:fs";
|
|
59913
61463
|
import path21 from "node:path";
|
|
59914
|
-
import { spawnSync as
|
|
61464
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
59915
61465
|
var vcsConfigPath = () => process.env.WORKFLOW_VCS_CONFIG ?? path21.join(configDir(), "vcs.json");
|
|
59916
61466
|
var vcsCwd = (cwd) => cwd ?? process.env.WORKFLOW_WORKSPACE_ROOT ?? process.cwd();
|
|
59917
61467
|
var remoteProvider = (cwd) => {
|
|
59918
|
-
const r =
|
|
61468
|
+
const r = spawnSync4("git", ["remote", "get-url", "origin"], { cwd, encoding: "utf8" });
|
|
59919
61469
|
if (r.status !== 0)
|
|
59920
61470
|
return null;
|
|
59921
61471
|
const url = (r.stdout ?? "").trim();
|
|
@@ -59952,7 +61502,7 @@ var remoteEndpoint = (remote) => {
|
|
|
59952
61502
|
var configuredSshEndpoint = (host) => {
|
|
59953
61503
|
if (host.startsWith("-"))
|
|
59954
61504
|
return null;
|
|
59955
|
-
const resolved =
|
|
61505
|
+
const resolved = spawnSync4("ssh", ["-G", host], {
|
|
59956
61506
|
encoding: "utf8",
|
|
59957
61507
|
timeout: 5000,
|
|
59958
61508
|
maxBuffer: 1024 * 1024,
|
|
@@ -60031,8 +61581,8 @@ function vcsConfig(mode, cwd) {
|
|
|
60031
61581
|
const hasWorkspacePolicy = typeof wp.preset === "string" && Object.hasOwn(PRESETS, wp.preset);
|
|
60032
61582
|
const policyDefault = resolveBranchPolicyFor(root).defaultTargetBranch;
|
|
60033
61583
|
const defaultTarget = String(wsVcs.defaultTargetBranch ?? (hasWorkspacePolicy ? policyDefault : cfg.defaultTargetBranch ?? policyDefault) ?? "develop");
|
|
60034
|
-
const linkIssues =
|
|
60035
|
-
const youtrackBaseUrl =
|
|
61584
|
+
const linkIssues = typeof wsYt.link_issues === "boolean" ? wsYt.link_issues : null;
|
|
61585
|
+
const youtrackBaseUrl = typeof wsYt.baseUrl === "string" ? wsYt.baseUrl : null;
|
|
60036
61586
|
let issuesProvider = null;
|
|
60037
61587
|
let linkOnPr = null;
|
|
60038
61588
|
if (provider === "github" && typeof wsIssues.provider === "string" && wsIssues.provider.toLowerCase() === "github") {
|
|
@@ -60103,7 +61653,7 @@ function vcsCliIdentity(cwd) {
|
|
|
60103
61653
|
PATH: process.env.PATH ?? "",
|
|
60104
61654
|
...provider === "github" ? { GH_HOST: host } : { GITLAB_HOST: host }
|
|
60105
61655
|
};
|
|
60106
|
-
const result =
|
|
61656
|
+
const result = spawnSync4(bin, ["api", "user"], {
|
|
60107
61657
|
cwd: root,
|
|
60108
61658
|
encoding: "utf8",
|
|
60109
61659
|
env
|
|
@@ -60145,7 +61695,7 @@ function mergedPrStyle(limit = 6, cwd) {
|
|
|
60145
61695
|
`).filter((l) => l.startsWith("## ")).map((l) => l.trim()),
|
|
60146
61696
|
descriptionPreview: desc.slice(0, 600)
|
|
60147
61697
|
});
|
|
60148
|
-
const remoteResult =
|
|
61698
|
+
const remoteResult = spawnSync4("git", ["remote", "get-url", "--push", "--all", "origin"], {
|
|
60149
61699
|
cwd,
|
|
60150
61700
|
encoding: "utf8"
|
|
60151
61701
|
});
|
|
@@ -60161,7 +61711,7 @@ function mergedPrStyle(limit = 6, cwd) {
|
|
|
60161
61711
|
if (!hostingApiHostMatches(remote, host))
|
|
60162
61712
|
return { ok: false, error: "PR style target does not match the provider host" };
|
|
60163
61713
|
if (provider === "gitlab") {
|
|
60164
|
-
const run = (args) =>
|
|
61714
|
+
const run = (args) => spawnSync4("glab", ["api", ...args], {
|
|
60165
61715
|
cwd,
|
|
60166
61716
|
encoding: "utf8",
|
|
60167
61717
|
env
|
|
@@ -60181,7 +61731,7 @@ function mergedPrStyle(limit = 6, cwd) {
|
|
|
60181
61731
|
});
|
|
60182
61732
|
}
|
|
60183
61733
|
} else if (provider === "github") {
|
|
60184
|
-
const r =
|
|
61734
|
+
const r = spawnSync4("gh", [
|
|
60185
61735
|
"pr",
|
|
60186
61736
|
"list",
|
|
60187
61737
|
"--repo",
|
|
@@ -60454,7 +62004,7 @@ var branchSetup = ({
|
|
|
60454
62004
|
};
|
|
60455
62005
|
const readManifest = () => {
|
|
60456
62006
|
try {
|
|
60457
|
-
return JSON.parse(
|
|
62007
|
+
return JSON.parse(readFileSync15(manifestPath, "utf8"));
|
|
60458
62008
|
} catch {
|
|
60459
62009
|
return {};
|
|
60460
62010
|
}
|
|
@@ -60650,7 +62200,7 @@ var OPERATION_CLASS = {
|
|
|
60650
62200
|
var operationAutoClass = (operation) => typeof operation === "string" ? OPERATION_CLASS[operation] ?? null : null;
|
|
60651
62201
|
var digestOf = (configDirPath) => {
|
|
60652
62202
|
try {
|
|
60653
|
-
const raw =
|
|
62203
|
+
const raw = readFileSync16(`${configDirPath}/workspaces.json`, "utf8");
|
|
60654
62204
|
return createHash8("sha256").update(raw).digest("hex");
|
|
60655
62205
|
} catch {
|
|
60656
62206
|
return null;
|
|
@@ -61458,7 +63008,7 @@ var compareCodeUnits2 = (left, right) => {
|
|
|
61458
63008
|
return left.length - right.length;
|
|
61459
63009
|
};
|
|
61460
63010
|
var gitPaths = (root) => {
|
|
61461
|
-
const result =
|
|
63011
|
+
const result = spawnSync5("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], {
|
|
61462
63012
|
cwd: root,
|
|
61463
63013
|
encoding: "buffer"
|
|
61464
63014
|
});
|
|
@@ -61471,7 +63021,7 @@ var gitPaths = (root) => {
|
|
|
61471
63021
|
};
|
|
61472
63022
|
}
|
|
61473
63023
|
const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path25.sep).join("/")) : [];
|
|
61474
|
-
const stagedDeleted =
|
|
63024
|
+
const stagedDeleted = spawnSync5("git", ["diff", "--cached", "--name-only", "--diff-filter=D", "-z"], { cwd: root, encoding: "buffer" });
|
|
61475
63025
|
if (stagedDeleted.status !== 0) {
|
|
61476
63026
|
const stderr = stagedDeleted.stderr?.toString("utf8") ?? "";
|
|
61477
63027
|
if (!/not a git repository/i.test(stderr))
|
|
@@ -61602,7 +63152,7 @@ function captureCandidate(root, scope, environment = []) {
|
|
|
61602
63152
|
const values = supplied.sort((left, right) => compareCodeUnits2(left.name, right.name)).map(({ name, value }) => ({ name, value, refs: [] }));
|
|
61603
63153
|
if (values.some(({ value }) => value === null))
|
|
61604
63154
|
completeness = "uncertain";
|
|
61605
|
-
const headResult =
|
|
63155
|
+
const headResult = spawnSync5("git", ["rev-parse", "HEAD"], { cwd: checkout, encoding: "utf8" });
|
|
61606
63156
|
if (headResult.status !== 0 && !/not a git repository/i.test(headResult.stderr ?? ""))
|
|
61607
63157
|
completeness = "uncertain";
|
|
61608
63158
|
const head = headResult.status === 0 ? headResult.stdout.trim() : null;
|
|
@@ -65090,7 +66640,7 @@ function resolveInside(root, candidate) {
|
|
|
65090
66640
|
}
|
|
65091
66641
|
function run2(root, executable, args, env = {}) {
|
|
65092
66642
|
const cwd = realpathSync10(root);
|
|
65093
|
-
const result =
|
|
66643
|
+
const result = spawnSync6(executable, args, {
|
|
65094
66644
|
cwd,
|
|
65095
66645
|
encoding: "utf8",
|
|
65096
66646
|
env: { ...process.env, ...env }
|
|
@@ -65106,7 +66656,7 @@ function run2(root, executable, args, env = {}) {
|
|
|
65106
66656
|
// packages/workit-core/src/core/pr-create.ts
|
|
65107
66657
|
import fs11 from "node:fs";
|
|
65108
66658
|
import path28 from "node:path";
|
|
65109
|
-
import { spawnSync as
|
|
66659
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
65110
66660
|
import { pathToFileURL } from "node:url";
|
|
65111
66661
|
var remoteRepoPath = (remote) => {
|
|
65112
66662
|
const raw = remote.trim();
|
|
@@ -65208,11 +66758,11 @@ function whichOnPath(tool) {
|
|
|
65208
66758
|
}
|
|
65209
66759
|
var hostingCliAvailable = (provider) => whichOnPath(provider === "gitlab" ? "glab" : "gh") !== null;
|
|
65210
66760
|
function repoRoot2(cwd) {
|
|
65211
|
-
const result =
|
|
66761
|
+
const result = spawnSync7("git", ["rev-parse", "--show-toplevel"], { cwd, encoding: "utf8" });
|
|
65212
66762
|
return result.status === 0 ? (result.stdout ?? "").trim() : cwd;
|
|
65213
66763
|
}
|
|
65214
66764
|
var pushRemote = (cwd) => {
|
|
65215
|
-
const result =
|
|
66765
|
+
const result = spawnSync7("git", ["remote", "get-url", "--push", "--all", "origin"], {
|
|
65216
66766
|
cwd,
|
|
65217
66767
|
encoding: "utf8"
|
|
65218
66768
|
});
|
|
@@ -65272,7 +66822,7 @@ var pushTargetIsStable = (cwd, remote) => {
|
|
|
65272
66822
|
const target = safePushUrl(remote);
|
|
65273
66823
|
if (!target)
|
|
65274
66824
|
return false;
|
|
65275
|
-
const result =
|
|
66825
|
+
const result = spawnSync7("git", ["config", "--get-regexp", "^url\\..*\\.(insteadof|pushinsteadof)$"], { cwd, encoding: "utf8" });
|
|
65276
66826
|
if (result.status !== 0 && result.status !== 1)
|
|
65277
66827
|
return false;
|
|
65278
66828
|
const prefixes = (result.stdout ?? "").split(/\r?\n/u).map((line) => line.trim().slice(line.trim().indexOf(" ") + 1)).filter(Boolean);
|
|
@@ -65320,12 +66870,12 @@ function prCreate(env, cwd) {
|
|
|
65320
66870
|
const resolvedDefault = String(cfg.defaultTargetBranch ?? policy.defaultTargetBranch ?? "develop");
|
|
65321
66871
|
const target = targetOverride || resolvedDefault;
|
|
65322
66872
|
const title = String(env.WF_PR_TITLE ?? "");
|
|
65323
|
-
const br =
|
|
66873
|
+
const br = spawnSync7("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
65324
66874
|
cwd: root,
|
|
65325
66875
|
encoding: "utf8"
|
|
65326
66876
|
});
|
|
65327
66877
|
const branch = br.status === 0 ? (br.stdout ?? "").trim() : "";
|
|
65328
|
-
const sourceResult = branch ?
|
|
66878
|
+
const sourceResult = branch ? spawnSync7("git", ["rev-parse", "--verify", `refs/heads/${branch}`], {
|
|
65329
66879
|
cwd: root,
|
|
65330
66880
|
encoding: "utf8"
|
|
65331
66881
|
}) : null;
|
|
@@ -65334,7 +66884,7 @@ function prCreate(env, cwd) {
|
|
|
65334
66884
|
return { error: "approved PR source branch and commit are incomplete" };
|
|
65335
66885
|
if (env.WORKIT_EXPECTED_SOURCE_BRANCH && env.WORKIT_EXPECTED_SOURCE_BRANCH !== branch || env.WORKIT_EXPECTED_SOURCE_COMMIT && env.WORKIT_EXPECTED_SOURCE_COMMIT !== sourceCommit)
|
|
65336
66886
|
return { error: "approved PR source branch or commit changed before execution" };
|
|
65337
|
-
const mergeBaseResult = policy.integration === "merge" ?
|
|
66887
|
+
const mergeBaseResult = policy.integration === "merge" ? spawnSync7("git", ["rev-parse", "--verify", `refs/heads/${target}`], {
|
|
65338
66888
|
cwd: root,
|
|
65339
66889
|
encoding: "utf8"
|
|
65340
66890
|
}) : null;
|
|
@@ -65350,7 +66900,7 @@ function prCreate(env, cwd) {
|
|
|
65350
66900
|
targetBranch: target,
|
|
65351
66901
|
stderr: "source or target branch commit could not be resolved"
|
|
65352
66902
|
};
|
|
65353
|
-
const merge =
|
|
66903
|
+
const merge = spawnSync7("git", ["merge", "--no-ff", sourceCommit, "-m", title], {
|
|
65354
66904
|
cwd: root,
|
|
65355
66905
|
encoding: "utf8"
|
|
65356
66906
|
});
|
|
@@ -65361,16 +66911,16 @@ function prCreate(env, cwd) {
|
|
|
65361
66911
|
targetBranch: target,
|
|
65362
66912
|
stderr: (merge.stderr ?? "").slice(0, 800)
|
|
65363
66913
|
};
|
|
65364
|
-
const mergedCommit =
|
|
66914
|
+
const mergedCommit = spawnSync7("git", ["rev-parse", "HEAD"], {
|
|
65365
66915
|
cwd: root,
|
|
65366
66916
|
encoding: "utf8"
|
|
65367
66917
|
});
|
|
65368
66918
|
if (mergedCommit.status !== 0)
|
|
65369
66919
|
return { error: "merge commit could not be resolved", mode: "merge" };
|
|
65370
|
-
const updateTarget =
|
|
66920
|
+
const updateTarget = spawnSync7("git", ["update-ref", `refs/heads/${target}`, mergedCommit.stdout.trim(), mergeBaseCommit], { cwd: root, encoding: "utf8" });
|
|
65371
66921
|
if (updateTarget.status !== 0)
|
|
65372
66922
|
return { error: "merge target branch changed before update", mode: "merge" };
|
|
65373
|
-
const push =
|
|
66923
|
+
const push = spawnSync7("git", ["push", targetUrl, `${mergedCommit.stdout.trim()}:refs/heads/${target}`], { cwd: root, encoding: "utf8", env: { ...process.env, PATH: process.env.PATH ?? "" } });
|
|
65374
66924
|
if (push.status !== 0)
|
|
65375
66925
|
return {
|
|
65376
66926
|
error: "push failed",
|
|
@@ -65387,7 +66937,7 @@ function prCreate(env, cwd) {
|
|
|
65387
66937
|
output: (push.stdout ?? "").trim()
|
|
65388
66938
|
};
|
|
65389
66939
|
};
|
|
65390
|
-
const co =
|
|
66940
|
+
const co = spawnSync7("git", ["checkout", "--detach", mergeBaseCommit], {
|
|
65391
66941
|
cwd: root,
|
|
65392
66942
|
encoding: "utf8"
|
|
65393
66943
|
});
|
|
@@ -65399,7 +66949,7 @@ function prCreate(env, cwd) {
|
|
|
65399
66949
|
stderr: (co.stderr ?? "").slice(0, 800)
|
|
65400
66950
|
};
|
|
65401
66951
|
const result = finish();
|
|
65402
|
-
|
|
66952
|
+
spawnSync7("git", ["checkout", branch], { cwd: root, encoding: "utf8" });
|
|
65403
66953
|
return result;
|
|
65404
66954
|
}
|
|
65405
66955
|
const pr = cfg.pr ?? {};
|
|
@@ -65425,7 +66975,7 @@ function prCreate(env, cwd) {
|
|
|
65425
66975
|
const push = pr.pushBranch !== false;
|
|
65426
66976
|
const skipConfirm = pr.confirmSkip !== false;
|
|
65427
66977
|
const remoteBranchTip = () => {
|
|
65428
|
-
const read =
|
|
66978
|
+
const read = spawnSync7("git", ["ls-remote", targetUrl, `refs/heads/${branch}`], {
|
|
65429
66979
|
cwd: root,
|
|
65430
66980
|
encoding: "utf8",
|
|
65431
66981
|
env: { ...process.env, PATH: process.env.PATH ?? "" }
|
|
@@ -65441,7 +66991,7 @@ function prCreate(env, cwd) {
|
|
|
65441
66991
|
stderr: branch ? "source branch commit could not be resolved" : "empty current branch (detached HEAD or unborn HEAD)"
|
|
65442
66992
|
};
|
|
65443
66993
|
if (push) {
|
|
65444
|
-
const pushed =
|
|
66994
|
+
const pushed = spawnSync7("git", ["push", "-u", targetUrl, `${sourceCommit}:refs/heads/${branch}`], { cwd: root, encoding: "utf8", env: { ...process.env, PATH: process.env.PATH ?? "" } });
|
|
65445
66995
|
if (pushed.status !== 0)
|
|
65446
66996
|
return { error: "push failed", provider, stderr: (pushed.stderr ?? "").slice(0, 800) };
|
|
65447
66997
|
}
|
|
@@ -65486,12 +67036,12 @@ function prCreate(env, cwd) {
|
|
|
65486
67036
|
cmd.push("--draft");
|
|
65487
67037
|
cmdEnv = { ...process.env, PATH: process.env.PATH ?? "", GH_HOST: identity.host };
|
|
65488
67038
|
}
|
|
65489
|
-
const result =
|
|
67039
|
+
const result = spawnSync7(cmd[0], cmd.slice(1), { cwd: root, encoding: "utf8", env: cmdEnv });
|
|
65490
67040
|
if (result.status !== 0) {
|
|
65491
67041
|
const err = (result.stderr ?? result.stdout ?? "").trim();
|
|
65492
67042
|
let hint = null;
|
|
65493
67043
|
if (provider === "gitlab" && (err.includes("409") || err.toLowerCase().includes("already exists"))) {
|
|
65494
|
-
const list =
|
|
67044
|
+
const list = spawnSync7("glab", ["mr", "list", `--source-branch=${branch}`, "--output=json"], {
|
|
65495
67045
|
cwd: root,
|
|
65496
67046
|
encoding: "utf8",
|
|
65497
67047
|
env: cmdEnv
|
|
@@ -65550,7 +67100,7 @@ function mergePr(cwd, opts) {
|
|
|
65550
67100
|
return { error: "approved hosting account changed before execution" };
|
|
65551
67101
|
if (!/^[a-f0-9]{40,64}$/i.test(opts.sourceCommit))
|
|
65552
67102
|
return { error: "approved merge source commit is invalid" };
|
|
65553
|
-
const currentCommit =
|
|
67103
|
+
const currentCommit = spawnSync7("git", ["rev-parse", "--verify", `refs/heads/${opts.source}`], {
|
|
65554
67104
|
cwd: root,
|
|
65555
67105
|
encoding: "utf8"
|
|
65556
67106
|
});
|
|
@@ -65564,7 +67114,7 @@ function mergePr(cwd, opts) {
|
|
|
65564
67114
|
return { error: `workflow CLI missing (required for ${provider})` };
|
|
65565
67115
|
const owner = repoPath.split("/")[0];
|
|
65566
67116
|
const endpoint = provider === "github" ? `repos/${repository.replace(/^[^/]+\//u, "")}/pulls?state=open&head=${encodeURIComponent(`${owner}:${opts.source}`)}&base=${encodeURIComponent(opts.target)}&per_page=100` : `projects/${encodeURIComponent(repoPath)}/merge_requests?state=opened&source_branch=${encodeURIComponent(opts.source)}&target_branch=${encodeURIComponent(opts.target)}&per_page=100`;
|
|
65567
|
-
const listOpen = () =>
|
|
67117
|
+
const listOpen = () => spawnSync7(provider === "github" ? "gh" : "glab", ["api", endpoint], {
|
|
65568
67118
|
cwd: root,
|
|
65569
67119
|
encoding: "utf8",
|
|
65570
67120
|
env: {
|
|
@@ -65624,7 +67174,7 @@ function mergePr(cwd, opts) {
|
|
|
65624
67174
|
cmd.push("--delete-branch");
|
|
65625
67175
|
cmdEnv = { ...process.env, PATH: process.env.PATH ?? "", GH_HOST: identity.host };
|
|
65626
67176
|
}
|
|
65627
|
-
const result =
|
|
67177
|
+
const result = spawnSync7(cmd[0], cmd.slice(1), { cwd: root, encoding: "utf8", env: cmdEnv });
|
|
65628
67178
|
if (result.status !== 0)
|
|
65629
67179
|
return {
|
|
65630
67180
|
error: "merge failed",
|
|
@@ -65641,8 +67191,8 @@ function mergePr(cwd, opts) {
|
|
|
65641
67191
|
}
|
|
65642
67192
|
|
|
65643
67193
|
// packages/workit-core/src/core/repo-context.ts
|
|
65644
|
-
import { spawnSync as
|
|
65645
|
-
import { existsSync as existsSync18, readFileSync as
|
|
67194
|
+
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
67195
|
+
import { existsSync as existsSync18, readFileSync as readFileSync19, readdirSync as readdirSync9 } from "node:fs";
|
|
65646
67196
|
import path29 from "node:path";
|
|
65647
67197
|
var isSafeContextRange = (value) => value.length <= 4096 && (() => {
|
|
65648
67198
|
try {
|
|
@@ -65670,7 +67220,7 @@ var invalidRange = (cwd) => ({
|
|
|
65670
67220
|
cwd
|
|
65671
67221
|
});
|
|
65672
67222
|
var runGit = (cwd, args) => {
|
|
65673
|
-
const result =
|
|
67223
|
+
const result = spawnSync8("git", args, { cwd, encoding: "utf8" });
|
|
65674
67224
|
return {
|
|
65675
67225
|
stdout: (result.stdout ?? "").trimEnd(),
|
|
65676
67226
|
stderr: (result.stderr ?? "").trimEnd(),
|
|
@@ -65812,7 +67362,7 @@ var packageScripts = (cwd, keys) => {
|
|
|
65812
67362
|
if (!existsSync18(pkgPath))
|
|
65813
67363
|
return [];
|
|
65814
67364
|
try {
|
|
65815
|
-
const pkg = JSON.parse(
|
|
67365
|
+
const pkg = JSON.parse(readFileSync19(pkgPath, "utf8"));
|
|
65816
67366
|
return keys.filter((k) => pkg.scripts && typeof pkg.scripts[k] === "string").map((k) => `${k}: ${pkg.scripts?.[k]}`);
|
|
65817
67367
|
} catch {
|
|
65818
67368
|
return [];
|
|
@@ -65846,7 +67396,7 @@ var documentationFiles = (cwd) => {
|
|
|
65846
67396
|
var readTrimmed = (file, maxLines) => {
|
|
65847
67397
|
if (!existsSync18(file))
|
|
65848
67398
|
return "";
|
|
65849
|
-
const lines =
|
|
67399
|
+
const lines = readFileSync19(file, "utf8").split(`
|
|
65850
67400
|
`);
|
|
65851
67401
|
return lines.slice(0, maxLines).join(`
|
|
65852
67402
|
`);
|
|
@@ -66034,7 +67584,7 @@ function docsRefreshContext(root, range) {
|
|
|
66034
67584
|
const pkgPath = path29.join(cwd, "package.json");
|
|
66035
67585
|
if (existsSync18(pkgPath)) {
|
|
66036
67586
|
try {
|
|
66037
|
-
const pkg = JSON.parse(
|
|
67587
|
+
const pkg = JSON.parse(readFileSync19(pkgPath, "utf8"));
|
|
66038
67588
|
stdout += JSON.stringify({ name: pkg.name, version: pkg.version, scripts: pkg.scripts }, null, 2) + `
|
|
66039
67589
|
`;
|
|
66040
67590
|
} catch {}
|
|
@@ -66111,7 +67661,7 @@ function releaseNotesContext(root, rangeOrTag) {
|
|
|
66111
67661
|
}
|
|
66112
67662
|
|
|
66113
67663
|
// packages/workit-core/src/core/tracker-issues.ts
|
|
66114
|
-
import { spawnSync as
|
|
67664
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
66115
67665
|
var repoPathFromRemote = (remote) => {
|
|
66116
67666
|
let rest = (remote || "").trim().replace(/\/+$/, "");
|
|
66117
67667
|
if (!rest)
|
|
@@ -66132,7 +67682,7 @@ var defaultCli = (bin, available) => {
|
|
|
66132
67682
|
if (!available)
|
|
66133
67683
|
return null;
|
|
66134
67684
|
return (args, root) => {
|
|
66135
|
-
const out =
|
|
67685
|
+
const out = spawnSync9(bin, args, {
|
|
66136
67686
|
cwd: root,
|
|
66137
67687
|
encoding: "utf8",
|
|
66138
67688
|
env: { ...process.env, PATH: process.env.PATH ?? "" }
|
|
@@ -66865,7 +68415,7 @@ async function logTimeUpdate(input, operation = defaultOperations) {
|
|
|
66865
68415
|
// packages/workit-core/src/core/external-action-effects.ts
|
|
66866
68416
|
import fs13 from "node:fs";
|
|
66867
68417
|
import path31 from "node:path";
|
|
66868
|
-
import { spawnSync as
|
|
68418
|
+
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
66869
68419
|
var run3 = (root, args) => {
|
|
66870
68420
|
return run2(root, "git", args);
|
|
66871
68421
|
};
|
|
@@ -67265,7 +68815,7 @@ var hostingProvider = (root, remote) => {
|
|
|
67265
68815
|
};
|
|
67266
68816
|
var remoteBranchTip = (root, provider, host, repo, branch) => {
|
|
67267
68817
|
const endpoint = provider === "github" ? `repos/${repo}/git/ref/heads/${branch.split("/").map(encodeURIComponent).join("/")}` : `projects/${encodeURIComponent(repo)}/repository/branches/${encodeURIComponent(branch)}`;
|
|
67268
|
-
const response =
|
|
68818
|
+
const response = spawnSync10(provider === "github" ? "gh" : "glab", ["api", endpoint], {
|
|
67269
68819
|
cwd: root,
|
|
67270
68820
|
encoding: "utf8",
|
|
67271
68821
|
env: hostingCliEnv(provider, host)
|
|
@@ -67273,7 +68823,7 @@ var remoteBranchTip = (root, provider, host, repo, branch) => {
|
|
|
67273
68823
|
if (response.status !== 0) {
|
|
67274
68824
|
if (/\b404\b/.test(response.stderr ?? "")) {
|
|
67275
68825
|
const project = provider === "github" ? `repos/${repo}` : `projects/${encodeURIComponent(repo)}`;
|
|
67276
|
-
const visible =
|
|
68826
|
+
const visible = spawnSync10(provider === "github" ? "gh" : "glab", ["api", project], {
|
|
67277
68827
|
cwd: root,
|
|
67278
68828
|
encoding: "utf8",
|
|
67279
68829
|
env: hostingCliEnv(provider, host)
|
|
@@ -67329,7 +68879,7 @@ var mergedBranch = (root, branch) => {
|
|
|
67329
68879
|
outcome: "not_started"
|
|
67330
68880
|
});
|
|
67331
68881
|
const endpoint = provider === "github" ? `repos/${repo}/pulls?state=closed&head=${encodeURIComponent(`${repo.split("/")[0]}:${branch}`)}&per_page=100` : `projects/${encodeURIComponent(repo)}/merge_requests?state=merged&source_branch=${encodeURIComponent(branch)}&per_page=100`;
|
|
67332
|
-
const response =
|
|
68882
|
+
const response = spawnSync10(provider === "github" ? "gh" : "glab", ["api", endpoint], {
|
|
67333
68883
|
cwd: root,
|
|
67334
68884
|
encoding: "utf8",
|
|
67335
68885
|
env: hostingCliEnv(provider, auth.host)
|
|
@@ -67391,7 +68941,7 @@ var readHostingAction = async (root, resolved, actionRef) => {
|
|
|
67391
68941
|
return unknownHostingEvidence(operation);
|
|
67392
68942
|
const endpoint = cfg.provider === "github" ? `repos/${repo}/pulls?state=all&head=${encodeURIComponent(`${repo.split("/")[0]}:${branch}`)}&base=${encodeURIComponent(target)}&per_page=100&page=1` : `projects/${encodeURIComponent(repo)}/merge_requests?state=all&source_branch=${encodeURIComponent(branch)}&target_branch=${encodeURIComponent(target)}&per_page=100&page=1`;
|
|
67393
68943
|
const cli = cfg.provider === "github" ? "gh" : "glab";
|
|
67394
|
-
const response =
|
|
68944
|
+
const response = spawnSync10(cli, ["api", endpoint], {
|
|
67395
68945
|
cwd: root,
|
|
67396
68946
|
encoding: "utf8",
|
|
67397
68947
|
env: hostingCliEnv(cfg.provider, auth.host)
|
|
@@ -68478,7 +70028,7 @@ async function payloadValue(raw, deps) {
|
|
|
68478
70028
|
return { ok: true, value: {} };
|
|
68479
70029
|
let source;
|
|
68480
70030
|
try {
|
|
68481
|
-
source = raw === "-" ? await readInput(deps.stdin ?? process.stdin) : raw.startsWith("@") ? decodeUtf8(
|
|
70031
|
+
source = raw === "-" ? await readInput(deps.stdin ?? process.stdin) : raw.startsWith("@") ? decodeUtf8(readFileSync20(raw.slice(1))) : raw;
|
|
68482
70032
|
} catch (error) {
|
|
68483
70033
|
return {
|
|
68484
70034
|
ok: false,
|
|
@@ -69191,6 +70741,498 @@ async function runActionCommand(argv, deps = {}) {
|
|
|
69191
70741
|
return result.ok ? 0 : 1;
|
|
69192
70742
|
}
|
|
69193
70743
|
|
|
70744
|
+
// packages/workit-cli/src/upgrade.ts
|
|
70745
|
+
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
70746
|
+
import {
|
|
70747
|
+
existsSync as existsSync19,
|
|
70748
|
+
readFileSync as readFileSync21,
|
|
70749
|
+
mkdirSync as mkdirSync9,
|
|
70750
|
+
copyFileSync as copyFileSync3,
|
|
70751
|
+
chmodSync,
|
|
70752
|
+
cpSync as cpSync4,
|
|
70753
|
+
lstatSync as lstatSync8
|
|
70754
|
+
} from "node:fs";
|
|
70755
|
+
import path32 from "node:path";
|
|
70756
|
+
import os11 from "node:os";
|
|
70757
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
70758
|
+
var HOSTS2 = ["opencode", "cursor", "codex", "pi"];
|
|
70759
|
+
var upgradePaths = (deps) => {
|
|
70760
|
+
const home = deps.home ?? deps.env?.HOME ?? os11.homedir();
|
|
70761
|
+
const env = {
|
|
70762
|
+
...process.env,
|
|
70763
|
+
...deps.home || deps.env?.HOME ? {
|
|
70764
|
+
HOME: home,
|
|
70765
|
+
CODEX_HOME: path32.join(home, ".codex"),
|
|
70766
|
+
PI_CODING_AGENT_DIR: path32.join(home, ".pi/agent"),
|
|
70767
|
+
XDG_CONFIG_HOME: path32.join(home, ".config"),
|
|
70768
|
+
WORKFLOW_TOOLKIT_CONFIG: undefined,
|
|
70769
|
+
WORKFLOW_TOOLKIT_CONFIG_DIR: undefined
|
|
70770
|
+
} : {},
|
|
70771
|
+
...deps.env,
|
|
70772
|
+
HOME: home
|
|
70773
|
+
};
|
|
70774
|
+
const xdg = env.XDG_CONFIG_HOME || path32.join(home, ".config");
|
|
70775
|
+
return {
|
|
70776
|
+
home,
|
|
70777
|
+
env,
|
|
70778
|
+
configDir: env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path32.join(xdg, "workit"),
|
|
70779
|
+
opencodeConfig: path32.join(xdg, "opencode/opencode.json"),
|
|
70780
|
+
piSettings: path32.join(env.PI_CODING_AGENT_DIR ?? path32.join(home, ".pi/agent"), "settings.json"),
|
|
70781
|
+
codexConfig: path32.join(env.CODEX_HOME ?? path32.join(home, ".codex"), "config.toml")
|
|
70782
|
+
};
|
|
70783
|
+
};
|
|
70784
|
+
var object2 = (file) => {
|
|
70785
|
+
if (!existsSync19(file))
|
|
70786
|
+
return null;
|
|
70787
|
+
let data;
|
|
70788
|
+
try {
|
|
70789
|
+
data = JSON.parse(readFileSync21(file, "utf8"));
|
|
70790
|
+
} catch {
|
|
70791
|
+
throw new Error(`${file} is not valid JSON; use the native host to inspect JSONC settings`);
|
|
70792
|
+
}
|
|
70793
|
+
if (!data || typeof data !== "object" || Array.isArray(data))
|
|
70794
|
+
throw new Error(`${file} is not a configuration object`);
|
|
70795
|
+
return data;
|
|
70796
|
+
};
|
|
70797
|
+
var digest2 = (file) => existsSync19(file) ? createHash11("sha256").update(readFileSync21(file)).digest("hex") : "missing";
|
|
70798
|
+
var runner = (deps) => deps.run ?? ((command, args) => {
|
|
70799
|
+
const { home, env } = upgradePaths(deps);
|
|
70800
|
+
let step;
|
|
70801
|
+
try {
|
|
70802
|
+
step = hostCommand(command, args, { home, env });
|
|
70803
|
+
} catch {
|
|
70804
|
+
return { status: 1, stdout: "" };
|
|
70805
|
+
}
|
|
70806
|
+
const result = runHostCommand(step, { home, env });
|
|
70807
|
+
return { status: result.exitCode, stdout: result.stdout };
|
|
70808
|
+
});
|
|
70809
|
+
var classify = (host, selector) => ({
|
|
70810
|
+
host,
|
|
70811
|
+
selector,
|
|
70812
|
+
kind: selector === `@brainervirus/workit-${host}` || selector === `@brainervirus/workit-${host}@latest` || selector === `npm:@brainervirus/workit-${host}` || selector === `npm:@brainervirus/workit-${host}@latest` ? "floating" : new RegExp(`^(?:npm:)?@brainervirus/workit-${host}@[^/]+$`).test(selector) ? "pinned" : "local"
|
|
70813
|
+
});
|
|
70814
|
+
var sources = (paths, run, hosts) => {
|
|
70815
|
+
const { home, opencodeConfig, piSettings } = paths;
|
|
70816
|
+
const result = [];
|
|
70817
|
+
if (hosts.includes("opencode") && existsSync19(opencodeConfig + "c"))
|
|
70818
|
+
throw new Error("OpenCode JSONC config is present; inspect effective native configuration before updating");
|
|
70819
|
+
const oc = hosts.includes("opencode") ? object2(opencodeConfig) : null;
|
|
70820
|
+
if (oc && [oc.plugins, oc.plugin].some((value) => value !== undefined && !Array.isArray(value)))
|
|
70821
|
+
throw new Error("OpenCode plugin registrations must be arrays");
|
|
70822
|
+
const plugins = [...oc?.plugins ?? [], ...oc?.plugin ?? []];
|
|
70823
|
+
for (const pin of plugins)
|
|
70824
|
+
if (typeof pin === "string" && isWorkitPlugin(pin))
|
|
70825
|
+
result.push(classify("opencode", pin));
|
|
70826
|
+
const cursor = hosts.includes("cursor") ? object2(path32.join(home, ".cursor/plugins/local/workit/package.json")) : null;
|
|
70827
|
+
if (cursor?.name === "@brainervirus/workit-cursor") {
|
|
70828
|
+
const mcp = object2(path32.join(home, ".cursor/mcp.json"));
|
|
70829
|
+
const args = mcp?.mcpServers?.workit?.args ?? [];
|
|
70830
|
+
const selector = args.find((arg) => typeof arg === "string" && arg.startsWith("--package="));
|
|
70831
|
+
result.push(classify("cursor", typeof selector === "string" ? selector.slice(10) : "local"));
|
|
70832
|
+
}
|
|
70833
|
+
const pi = hosts.includes("pi") ? object2(piSettings) : null;
|
|
70834
|
+
if (pi?.packages !== undefined && !Array.isArray(pi.packages))
|
|
70835
|
+
throw new Error("Pi package registrations must be an array");
|
|
70836
|
+
for (const entry of pi?.packages ?? []) {
|
|
70837
|
+
const source = typeof entry === "string" ? entry : entry?.source;
|
|
70838
|
+
if (typeof source !== "string")
|
|
70839
|
+
continue;
|
|
70840
|
+
const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
|
|
70841
|
+
const local = path32.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path32.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
|
|
70842
|
+
if (npm || local)
|
|
70843
|
+
result.push(classify("pi", source));
|
|
70844
|
+
}
|
|
70845
|
+
const listing = hosts.includes("codex") ? run("codex", ["plugin", "list", "--json"]) : { status: 1, stdout: "" };
|
|
70846
|
+
if (hosts.includes("codex") && listing.status !== 0) {
|
|
70847
|
+
let available = false;
|
|
70848
|
+
try {
|
|
70849
|
+
hostCommand("codex", [], { home, env: paths.env });
|
|
70850
|
+
available = true;
|
|
70851
|
+
} catch {}
|
|
70852
|
+
if (available || existsSync19(paths.codexConfig))
|
|
70853
|
+
throw new Error("Codex plugin inventory failed; inspect the native host before upgrading");
|
|
70854
|
+
}
|
|
70855
|
+
if (listing.status === 0) {
|
|
70856
|
+
let installed;
|
|
70857
|
+
try {
|
|
70858
|
+
installed = JSON.parse(listing.stdout).installed ?? [];
|
|
70859
|
+
} catch {
|
|
70860
|
+
throw new Error("Codex plugin inventory could not be parsed");
|
|
70861
|
+
}
|
|
70862
|
+
if (!Array.isArray(installed))
|
|
70863
|
+
throw new Error("Codex plugin inventory is malformed");
|
|
70864
|
+
for (const plugin of installed) {
|
|
70865
|
+
if (plugin.name !== "workit")
|
|
70866
|
+
continue;
|
|
70867
|
+
const source = plugin.source;
|
|
70868
|
+
const npm = plugin.marketplaceName === "workflow-toolkit" && source?.source === "npm" && source?.package === "@brainervirus/workit-codex";
|
|
70869
|
+
result.push({
|
|
70870
|
+
...classify("codex", npm ? `${source.package}${source.version ? `@${source.version}` : ""}` : "local"),
|
|
70871
|
+
installedVersion: plugin.version
|
|
70872
|
+
});
|
|
70873
|
+
}
|
|
70874
|
+
}
|
|
70875
|
+
for (const source of result) {
|
|
70876
|
+
if (source.host === "cursor")
|
|
70877
|
+
source.installedVersion = cursor?.version;
|
|
70878
|
+
if (source.host === "pi" && source.kind === "floating") {
|
|
70879
|
+
const inventory = run("pi", ["list"]);
|
|
70880
|
+
if (inventory.status === 0)
|
|
70881
|
+
source.installedVersion = piInstalledVersion(inventory.stdout, source.selector);
|
|
70882
|
+
}
|
|
70883
|
+
}
|
|
70884
|
+
return result;
|
|
70885
|
+
};
|
|
70886
|
+
var piInstalledVersion = (listing, selector) => {
|
|
70887
|
+
const lines = listing.split(/\r?\n/).map((line) => line.trim());
|
|
70888
|
+
const index = lines.indexOf(selector);
|
|
70889
|
+
if (index < 0 || !lines[index + 1] || !path32.isAbsolute(lines[index + 1]))
|
|
70890
|
+
return;
|
|
70891
|
+
const pkg = object2(path32.join(lines[index + 1], "package.json"));
|
|
70892
|
+
return pkg?.name === "@brainervirus/workit-pi" ? pkg.version : undefined;
|
|
70893
|
+
};
|
|
70894
|
+
var versionAtLeast = (installed, latest) => {
|
|
70895
|
+
if (!/^\d+\.\d+\.\d+$/.test(installed))
|
|
70896
|
+
return false;
|
|
70897
|
+
const current = installed.split(".").map(Number);
|
|
70898
|
+
const target = latest.split(".").map(Number);
|
|
70899
|
+
for (let index = 0;index < 3; index++) {
|
|
70900
|
+
if (current[index] !== target[index])
|
|
70901
|
+
return current[index] > target[index];
|
|
70902
|
+
}
|
|
70903
|
+
return true;
|
|
70904
|
+
};
|
|
70905
|
+
function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
70906
|
+
const paths = upgradePaths(deps);
|
|
70907
|
+
const { home, configDir } = paths;
|
|
70908
|
+
const run = runner(deps);
|
|
70909
|
+
const state = readSetupState(configDir);
|
|
70910
|
+
const plan = {
|
|
70911
|
+
ok: true,
|
|
70912
|
+
blocked: [],
|
|
70913
|
+
skipped: [],
|
|
70914
|
+
entries: [],
|
|
70915
|
+
configDigests: {},
|
|
70916
|
+
migrations: []
|
|
70917
|
+
};
|
|
70918
|
+
for (const file of [state.config, state.workspaces, state.youtrack, state.vcs]) {
|
|
70919
|
+
if (file.status === "malformed")
|
|
70920
|
+
plan.blocked.push(file.error ?? file.file);
|
|
70921
|
+
plan.configDigests[file.file] = digest2(file.file);
|
|
70922
|
+
}
|
|
70923
|
+
for (const file of [
|
|
70924
|
+
paths.opencodeConfig,
|
|
70925
|
+
paths.opencodeConfig + "c",
|
|
70926
|
+
path32.join(home, ".cursor/settings.json"),
|
|
70927
|
+
path32.join(home, ".cursor/mcp.json"),
|
|
70928
|
+
path32.join(home, ".cursor/plugins/local/workit/package.json"),
|
|
70929
|
+
paths.codexConfig,
|
|
70930
|
+
paths.piSettings
|
|
70931
|
+
])
|
|
70932
|
+
plan.configDigests[file] = digest2(file);
|
|
70933
|
+
try {
|
|
70934
|
+
const config = object2(state.config.file);
|
|
70935
|
+
if (config && Object.hasOwn(config, "trustedPaths"))
|
|
70936
|
+
plan.migrations.push({
|
|
70937
|
+
id: "2.0-remove-ignored-trusted-paths",
|
|
70938
|
+
file: state.config.file,
|
|
70939
|
+
description: "Remove ignored Workit trustedPaths; native host permissions remain unchanged"
|
|
70940
|
+
});
|
|
70941
|
+
const installedSources = sources(paths, run, hosts);
|
|
70942
|
+
for (const host of ["opencode", "pi"]) {
|
|
70943
|
+
if (new Set(installedSources.filter((source) => source.host === host).map((source) => source.selector)).size > 1)
|
|
70944
|
+
plan.blocked.push(`${host}: conflicting Workit registrations; reconcile them in the native host before upgrading`);
|
|
70945
|
+
}
|
|
70946
|
+
for (const source of installedSources.filter((source, index, list) => list.findIndex((entry) => entry.host === source.host && entry.selector === source.selector) === index)) {
|
|
70947
|
+
if (source.kind !== "floating") {
|
|
70948
|
+
plan.skipped.push({
|
|
70949
|
+
host: source.host,
|
|
70950
|
+
reason: `${source.kind} source preserved; change its source explicitly to upgrade`
|
|
70951
|
+
});
|
|
70952
|
+
continue;
|
|
70953
|
+
}
|
|
70954
|
+
if (source.host === "opencode") {
|
|
70955
|
+
plan.skipped.push({
|
|
70956
|
+
host: source.host,
|
|
70957
|
+
reason: "OpenCode server plugin preserved: scoped native updates are unavailable in qualified 2.0.21; Workit never updates unrelated plugins"
|
|
70958
|
+
});
|
|
70959
|
+
continue;
|
|
70960
|
+
}
|
|
70961
|
+
const latest = run("npm", ["view", `@brainervirus/workit-${source.host}`, "version"]);
|
|
70962
|
+
if (latest.status !== 0 || !/^\d+\.\d+\.\d+$/.test(latest.stdout.trim())) {
|
|
70963
|
+
plan.blocked.push(`${source.host}: registry version unavailable; existing installation preserved`);
|
|
70964
|
+
continue;
|
|
70965
|
+
}
|
|
70966
|
+
if (source.installedVersion && versionAtLeast(source.installedVersion, latest.stdout.trim())) {
|
|
70967
|
+
plan.skipped.push({
|
|
70968
|
+
host: source.host,
|
|
70969
|
+
reason: `already current (${source.installedVersion})`
|
|
70970
|
+
});
|
|
70971
|
+
continue;
|
|
70972
|
+
}
|
|
70973
|
+
const commands = source.host === "pi" ? [{ command: "pi", args: ["update", "--extension", source.selector] }] : source.host === "codex" ? [{ command: "codex", args: ["plugin", "add", "workit@workflow-toolkit", "--json"] }] : planHostInstall("cursor", {
|
|
70974
|
+
home,
|
|
70975
|
+
env: deps.env,
|
|
70976
|
+
cwd: home,
|
|
70977
|
+
packageVersion: latest.stdout.trim(),
|
|
70978
|
+
targetDir: path32.join(home, ".cursor/plugins/local/workit")
|
|
70979
|
+
});
|
|
70980
|
+
plan.entries.push({
|
|
70981
|
+
host: source.host,
|
|
70982
|
+
selector: source.selector,
|
|
70983
|
+
latest: latest.stdout.trim(),
|
|
70984
|
+
commands
|
|
70985
|
+
});
|
|
70986
|
+
}
|
|
70987
|
+
} catch (error) {
|
|
70988
|
+
plan.blocked.push(error instanceof Error ? error.message : "installed source could not be read");
|
|
70989
|
+
}
|
|
70990
|
+
plan.ok = plan.blocked.length === 0;
|
|
70991
|
+
return plan;
|
|
70992
|
+
}
|
|
70993
|
+
function applyUpgrade(plan, deps = {}) {
|
|
70994
|
+
if (!plan.ok)
|
|
70995
|
+
return { ok: false, error: plan.blocked.join("; ") };
|
|
70996
|
+
if (!plan.entries.length && !plan.migrations.length && !plan.cli)
|
|
70997
|
+
return { ok: true };
|
|
70998
|
+
for (const [file, expected] of Object.entries(plan.configDigests))
|
|
70999
|
+
if (digest2(file) !== expected)
|
|
71000
|
+
return { ok: false, error: `configuration changed; preview again: ${file}` };
|
|
71001
|
+
const { home, env, configDir } = upgradePaths(deps);
|
|
71002
|
+
const active = deps.activeHosts?.() ?? runningHosts(deps);
|
|
71003
|
+
if (plan.entries.some((entry) => active.includes(entry.host)))
|
|
71004
|
+
return {
|
|
71005
|
+
ok: false,
|
|
71006
|
+
error: "Stop the selected running hosts before upgrading their loaded plugins"
|
|
71007
|
+
};
|
|
71008
|
+
const backup = path32.join(home, ".local/state/workit/upgrades", new Date().toISOString().replaceAll(":", "-"));
|
|
71009
|
+
mkdirSync9(backup, { recursive: true, mode: 448 });
|
|
71010
|
+
for (const file of Object.keys(plan.configDigests))
|
|
71011
|
+
if (existsSync19(file)) {
|
|
71012
|
+
const target = path32.join(backup, createHash11("sha256").update(file).digest("hex").slice(0, 12) + "-" + path32.basename(file));
|
|
71013
|
+
copyFileSync3(file, target);
|
|
71014
|
+
chmodSync(target, 384);
|
|
71015
|
+
}
|
|
71016
|
+
for (const migration of plan.migrations) {
|
|
71017
|
+
const value = object2(migration.file);
|
|
71018
|
+
if (migration.id !== "2.0-remove-ignored-trusted-paths" || !value)
|
|
71019
|
+
return {
|
|
71020
|
+
ok: false,
|
|
71021
|
+
backup,
|
|
71022
|
+
error: "Unknown configuration migration; upgrade the CLI before applying"
|
|
71023
|
+
};
|
|
71024
|
+
delete value.trustedPaths;
|
|
71025
|
+
writeFileAtomic(migration.file, JSON.stringify(value, null, 2) + `
|
|
71026
|
+
`, 384);
|
|
71027
|
+
}
|
|
71028
|
+
const run = runner(deps);
|
|
71029
|
+
const cursorRoot = path32.join(home, ".cursor/plugins/local/workit");
|
|
71030
|
+
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync19(cursorRoot))
|
|
71031
|
+
cpSync4(cursorRoot, path32.join(backup, "cursor-package"), { recursive: true });
|
|
71032
|
+
for (const entry of plan.entries) {
|
|
71033
|
+
if (entry.host === "opencode")
|
|
71034
|
+
return {
|
|
71035
|
+
ok: false,
|
|
71036
|
+
backup,
|
|
71037
|
+
error: "Scoped OpenCode server-plugin updates are unsupported; registration preserved"
|
|
71038
|
+
};
|
|
71039
|
+
if (entry.host === "cursor") {
|
|
71040
|
+
const preview = {
|
|
71041
|
+
ok: true,
|
|
71042
|
+
blocked: [],
|
|
71043
|
+
preserved: [],
|
|
71044
|
+
overrides: [],
|
|
71045
|
+
platforms: ["cursor"],
|
|
71046
|
+
state: readSetupState(configDir),
|
|
71047
|
+
mutations: [
|
|
71048
|
+
{
|
|
71049
|
+
type: "install-host",
|
|
71050
|
+
platform: "cursor",
|
|
71051
|
+
path: path32.join(home, ".cursor/plugins/local/.workit-package-bootstrap"),
|
|
71052
|
+
commands: entry.commands.map((command) => ({
|
|
71053
|
+
...command,
|
|
71054
|
+
purpose: command.purpose ?? "Upgrade Cursor"
|
|
71055
|
+
}))
|
|
71056
|
+
},
|
|
71057
|
+
{
|
|
71058
|
+
type: "install-adapter",
|
|
71059
|
+
platform: "cursor",
|
|
71060
|
+
path: path32.join(home, ".cursor/plugins/local/workit")
|
|
71061
|
+
}
|
|
71062
|
+
]
|
|
71063
|
+
};
|
|
71064
|
+
const result = applySetupPreview(preview, {
|
|
71065
|
+
home,
|
|
71066
|
+
env,
|
|
71067
|
+
cwd: home,
|
|
71068
|
+
preferInstalledAdapter: true,
|
|
71069
|
+
runHostCommand: (command) => {
|
|
71070
|
+
const outcome = run(command.command, command.args);
|
|
71071
|
+
return { exitCode: outcome.status ?? 1, stdout: outcome.stdout, stderr: "" };
|
|
71072
|
+
}
|
|
71073
|
+
});
|
|
71074
|
+
const pkg = object2(path32.join(home, ".cursor/plugins/local/workit/package.json"));
|
|
71075
|
+
if (!result.ok || pkg?.version !== entry.latest)
|
|
71076
|
+
return {
|
|
71077
|
+
ok: false,
|
|
71078
|
+
backup,
|
|
71079
|
+
error: "Cursor update did not verify the requested package version; inspect the installer before retrying"
|
|
71080
|
+
};
|
|
71081
|
+
continue;
|
|
71082
|
+
}
|
|
71083
|
+
for (const command of entry.commands)
|
|
71084
|
+
if (run(command.command, command.args).status !== 0)
|
|
71085
|
+
return {
|
|
71086
|
+
ok: false,
|
|
71087
|
+
backup,
|
|
71088
|
+
error: `${entry.host}: update failed; inspect the native host before retrying`
|
|
71089
|
+
};
|
|
71090
|
+
const verify = entry.host === "codex" ? run("codex", ["plugin", "list", "--json"]) : run("pi", ["list"]);
|
|
71091
|
+
if (verify.status !== 0)
|
|
71092
|
+
return { ok: false, backup, error: `${entry.host}: update verification failed` };
|
|
71093
|
+
if (entry.host === "codex") {
|
|
71094
|
+
let installed = [];
|
|
71095
|
+
try {
|
|
71096
|
+
installed = JSON.parse(verify.stdout).installed ?? [];
|
|
71097
|
+
} catch {}
|
|
71098
|
+
if (!installed.some((plugin) => plugin.name === "workit" && plugin.marketplaceName === "workflow-toolkit" && plugin.version === entry.latest))
|
|
71099
|
+
return { ok: false, backup, error: "Codex did not report the requested Workit version" };
|
|
71100
|
+
}
|
|
71101
|
+
if (entry.host === "pi" && piInstalledVersion(verify.stdout, entry.selector) !== entry.latest)
|
|
71102
|
+
return { ok: false, backup, error: "Pi did not report the requested Workit package version" };
|
|
71103
|
+
}
|
|
71104
|
+
if (plan.cli) {
|
|
71105
|
+
const currentRoot = run("npm", ["root", "--global"]);
|
|
71106
|
+
if (currentRoot.status !== 0 || currentRoot.stdout.trim() !== plan.cli.root)
|
|
71107
|
+
return { ok: false, backup, error: "Global npm location changed; preview again" };
|
|
71108
|
+
const cliBackup = path32.join(backup, "cli-package");
|
|
71109
|
+
cpSync4(path32.join(plan.cli.root, "@brainervirus/workit-cli"), cliBackup, { recursive: true });
|
|
71110
|
+
if (run("npm", ["install", "--global", `@brainervirus/workit-cli@${plan.cli.latest}`]).status !== 0)
|
|
71111
|
+
return {
|
|
71112
|
+
ok: false,
|
|
71113
|
+
backup,
|
|
71114
|
+
error: `CLI update failed; preserved package at ${cliBackup}; use npm to repair or run node ${path32.join(cliBackup, "dist/index.js")}`
|
|
71115
|
+
};
|
|
71116
|
+
const installed = object2(path32.join(plan.cli.root, "@brainervirus/workit-cli/package.json"));
|
|
71117
|
+
if (installed?.name !== "@brainervirus/workit-cli" || installed.version !== plan.cli.latest)
|
|
71118
|
+
return {
|
|
71119
|
+
ok: false,
|
|
71120
|
+
backup,
|
|
71121
|
+
error: `CLI update did not verify the requested version; preserved package at ${cliBackup}`
|
|
71122
|
+
};
|
|
71123
|
+
}
|
|
71124
|
+
return { ok: true, backup };
|
|
71125
|
+
}
|
|
71126
|
+
async function runUpgradeCommand(argv, deps = {}) {
|
|
71127
|
+
const out = deps.out ?? process.stdout;
|
|
71128
|
+
const flags = new Set(argv);
|
|
71129
|
+
const unknown = argv.filter((arg) => !["--apply", "--confirm", "--json", "--cli"].includes(arg) && !arg.startsWith("--hosts="));
|
|
71130
|
+
const hostFlag = argv.find((arg) => arg.startsWith("--hosts="))?.slice(8);
|
|
71131
|
+
const raw = hostFlag === "none" ? [] : hostFlag?.split(",") ?? HOSTS2;
|
|
71132
|
+
if (unknown.length || raw.some((host) => !HOSTS2.includes(host))) {
|
|
71133
|
+
out.write(`Usage: workit upgrade [--hosts=opencode,cursor,codex,pi|none] [--cli] [--apply --confirm] [--json]
|
|
71134
|
+
`);
|
|
71135
|
+
return 2;
|
|
71136
|
+
}
|
|
71137
|
+
const plan = previewUpgrade(raw, deps);
|
|
71138
|
+
if (flags.has("--cli")) {
|
|
71139
|
+
const run = runner(deps);
|
|
71140
|
+
const root = run("npm", ["root", "--global"]);
|
|
71141
|
+
if (root.status !== 0 || !path32.isAbsolute(root.stdout.trim())) {
|
|
71142
|
+
plan.blocked.push("Global npm location could not be verified");
|
|
71143
|
+
} else {
|
|
71144
|
+
const packageFile = path32.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
|
|
71145
|
+
const pkg = object2(packageFile);
|
|
71146
|
+
if (pkg?.name !== "@brainervirus/workit-cli" || lstatSync8(path32.dirname(packageFile)).isSymbolicLink()) {
|
|
71147
|
+
plan.skipped.push({
|
|
71148
|
+
host: "cli",
|
|
71149
|
+
reason: "No managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
|
|
71150
|
+
});
|
|
71151
|
+
} else {
|
|
71152
|
+
const latest = run("npm", ["view", "@brainervirus/workit-cli", "version"]);
|
|
71153
|
+
if (latest.status !== 0 || !/^\d+\.\d+\.\d+$/.test(latest.stdout.trim()))
|
|
71154
|
+
plan.blocked.push("CLI registry version unavailable; existing installation preserved");
|
|
71155
|
+
else if (!versionAtLeast(pkg.version, latest.stdout.trim())) {
|
|
71156
|
+
plan.cli = { latest: latest.stdout.trim(), root: root.stdout.trim() };
|
|
71157
|
+
plan.configDigests[packageFile] = digest2(packageFile);
|
|
71158
|
+
} else
|
|
71159
|
+
plan.skipped.push({ host: "cli", reason: `already current (${pkg.version})` });
|
|
71160
|
+
}
|
|
71161
|
+
}
|
|
71162
|
+
plan.ok = plan.blocked.length === 0;
|
|
71163
|
+
}
|
|
71164
|
+
if (!flags.has("--apply")) {
|
|
71165
|
+
out.write(JSON.stringify(plan, null, 2) + `
|
|
71166
|
+
`);
|
|
71167
|
+
return plan.ok ? 0 : 1;
|
|
71168
|
+
}
|
|
71169
|
+
if (!flags.has("--confirm")) {
|
|
71170
|
+
out.write(`Apply requires --confirm after reviewing the upgrade preview.
|
|
71171
|
+
`);
|
|
71172
|
+
return 2;
|
|
71173
|
+
}
|
|
71174
|
+
const result = applyUpgrade(plan, deps);
|
|
71175
|
+
out.write(JSON.stringify(result, null, 2) + `
|
|
71176
|
+
`);
|
|
71177
|
+
return result.ok ? 0 : 1;
|
|
71178
|
+
}
|
|
71179
|
+
async function runLaunchCommand(argv, deps = {}) {
|
|
71180
|
+
const [host, ...args] = argv;
|
|
71181
|
+
if (!HOSTS2.includes(host)) {
|
|
71182
|
+
(deps.out ?? process.stdout).write(`Usage: workit launch <opencode|cursor|codex|pi> [--auto-upgrade] [-- host arguments]
|
|
71183
|
+
`);
|
|
71184
|
+
return 2;
|
|
71185
|
+
}
|
|
71186
|
+
const auto = args[0] === "--auto-upgrade";
|
|
71187
|
+
const rest = auto ? args.slice(1) : args;
|
|
71188
|
+
const hostArgs = rest[0] === "--" ? rest.slice(1) : rest;
|
|
71189
|
+
const { home, env } = upgradePaths(deps);
|
|
71190
|
+
let launch;
|
|
71191
|
+
if (!deps.run) {
|
|
71192
|
+
try {
|
|
71193
|
+
launch = hostCommand(host, hostArgs, { home, env });
|
|
71194
|
+
} catch (error) {
|
|
71195
|
+
(deps.out ?? process.stderr).write(`${error instanceof Error ? error.message : "Host executable unavailable"}
|
|
71196
|
+
`);
|
|
71197
|
+
return 1;
|
|
71198
|
+
}
|
|
71199
|
+
}
|
|
71200
|
+
if (auto) {
|
|
71201
|
+
const plan = previewUpgrade([host], deps);
|
|
71202
|
+
if (plan.ok) {
|
|
71203
|
+
for (const skipped of plan.skipped)
|
|
71204
|
+
(deps.out ?? process.stderr).write(`${skipped.host}: ${skipped.reason}
|
|
71205
|
+
`);
|
|
71206
|
+
const result = applyUpgrade(plan, deps);
|
|
71207
|
+
if (!result.ok) {
|
|
71208
|
+
(deps.out ?? process.stdout).write(`${result.error}
|
|
71209
|
+
`);
|
|
71210
|
+
return 1;
|
|
71211
|
+
}
|
|
71212
|
+
} else if (plan.blocked.every((reason) => reason.includes("registry version unavailable"))) {
|
|
71213
|
+
(deps.out ?? process.stderr).write(`Upgrade unavailable: ${plan.blocked.join("; ")}. Starting the unchanged host.
|
|
71214
|
+
`);
|
|
71215
|
+
} else {
|
|
71216
|
+
(deps.out ?? process.stderr).write(`Upgrade blocked: ${plan.blocked.join("; ")}
|
|
71217
|
+
`);
|
|
71218
|
+
return 1;
|
|
71219
|
+
}
|
|
71220
|
+
}
|
|
71221
|
+
if (deps.run)
|
|
71222
|
+
return deps.run(host, hostArgs).status ?? 1;
|
|
71223
|
+
return spawnSync11(launch.command, launch.args, {
|
|
71224
|
+
stdio: "inherit",
|
|
71225
|
+
env
|
|
71226
|
+
}).status ?? 1;
|
|
71227
|
+
}
|
|
71228
|
+
var runningHosts = (deps) => {
|
|
71229
|
+
const run = runner(deps);
|
|
71230
|
+
const list = process.platform === "win32" ? run("tasklist", ["/fo", "csv", "/nh"]) : run("ps", ["-eo", "comm="]);
|
|
71231
|
+
if (list.status !== 0)
|
|
71232
|
+
return HOSTS2;
|
|
71233
|
+
return HOSTS2.filter((host) => new RegExp(`(?:^|[\\/",\\s])${host}(?:\\.exe)?(?:[",\\s]|$)`, "im").test(list.stdout));
|
|
71234
|
+
};
|
|
71235
|
+
|
|
69194
71236
|
// packages/workit-cli/src/index.tsx
|
|
69195
71237
|
var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
|
|
69196
71238
|
var logger = createLogger({
|
|
@@ -69215,6 +71257,8 @@ var HELP = `workit — workflow rails for agentic coding
|
|
|
69215
71257
|
|
|
69216
71258
|
Usage:
|
|
69217
71259
|
workit init Run the interactive setup wizard
|
|
71260
|
+
workit upgrade Preview upgrades (--apply --confirm; --hosts=a,b; --cli for the CLI)
|
|
71261
|
+
workit launch <host> [--auto-upgrade] [-- args] Upgrade before host startup
|
|
69218
71262
|
workit doctor Verify the offline installation health (add --json for a machine-readable report)
|
|
69219
71263
|
workit uninstall Remove workit host registrations interactively (~/.config/workit is kept)
|
|
69220
71264
|
workit cutover Preview or apply an explicit v1 cutover (apply requires --confirm)
|
|
@@ -69223,7 +71267,7 @@ ${COMMAND_DESCRIPTIONS.map(([cmd, desc]) => ` ${cmd.padEnd(helpColumn)}${desc}`
|
|
|
69223
71267
|
action payloads: ${externalActionHelp}
|
|
69224
71268
|
workit Show this help
|
|
69225
71269
|
|
|
69226
|
-
Run \`npx workit init\` to configure platforms, YouTrack, VCS and project hygiene.
|
|
71270
|
+
Run \`npx @brainervirus/workit-cli init\` to configure platforms, YouTrack, VCS and project hygiene.
|
|
69227
71271
|
`;
|
|
69228
71272
|
function printApplySummary(result) {
|
|
69229
71273
|
for (const entry of result.entries) {
|
|
@@ -69437,7 +71481,11 @@ if (__require.main == __require.module) {
|
|
|
69437
71481
|
logger.error(EVENT.uncaughtFailure, { phase: "uncaughtException", ...errorDetail(err) });
|
|
69438
71482
|
process.exit(1);
|
|
69439
71483
|
});
|
|
69440
|
-
if (subcommand === "
|
|
71484
|
+
if (subcommand === "upgrade") {
|
|
71485
|
+
process.exit(await runUpgradeCommand(args.slice(1)));
|
|
71486
|
+
} else if (subcommand === "launch") {
|
|
71487
|
+
process.exit(await runLaunchCommand(args.slice(1)));
|
|
71488
|
+
} else if (subcommand === "init") {
|
|
69441
71489
|
await runInit();
|
|
69442
71490
|
} else if (subcommand === "doctor") {
|
|
69443
71491
|
runDoctorCommand(args);
|