@brainervirus/workit-mcp 8.0.1 → 8.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +234 -135
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -16574,7 +16574,7 @@ class StdioServerTransport {
16574
16574
  import { fileURLToPath as fileURLToPath2 } from "node:url";
16575
16575
 
16576
16576
  // packages/workit-core/src/core.ts
16577
- import { spawnSync as spawnSync12 } from "node:child_process";
16577
+ import { spawnSync as spawnSync14 } from "node:child_process";
16578
16578
  import { existsSync as existsSync7, realpathSync as realpathSync5 } from "node:fs";
16579
16579
  import path19 from "node:path";
16580
16580
 
@@ -22691,73 +22691,8 @@ var exportDigest = (bundle) => sha256({
22691
22691
  sourceWorkspaceId: bundle.sourceWorkspaceId,
22692
22692
  task: bundle.task
22693
22693
  });
22694
- // packages/workit-core/src/core/git.ts
22695
- import { execFileSync } from "node:child_process";
22696
- var run = (cwd, args) => {
22697
- try {
22698
- const stdout = execFileSync("git", args, {
22699
- cwd,
22700
- encoding: "utf8",
22701
- stdio: ["pipe", "pipe", "pipe"]
22702
- });
22703
- return { stdout: stdout.trimEnd(), stderr: "", exitCode: 0 };
22704
- } catch (error) {
22705
- const e = error;
22706
- return {
22707
- stdout: (e.stdout ?? "").trimEnd(),
22708
- stderr: (e.stderr ?? "").trimEnd(),
22709
- exitCode: e.status ?? 1
22710
- };
22711
- }
22712
- };
22713
- var gitContext = (workspaceRoot, paths = []) => {
22714
- const cwd = workspaceRoot;
22715
- let failure;
22716
- const runHere = (args) => {
22717
- const result = run(cwd, args);
22718
- if (!failure && result.exitCode !== 0) {
22719
- failure = { stderr: result.stderr, exitCode: result.exitCode };
22720
- }
22721
- return result.stdout;
22722
- };
22723
- const branch = runHere(["rev-parse", "--abbrev-ref", "HEAD"]) || "unknown";
22724
- const status_short = runHere(["status", "--porcelain"]);
22725
- const staged = [];
22726
- const unstaged = [];
22727
- const untracked = [];
22728
- for (const line of status_short.split(`
22729
- `).filter(Boolean)) {
22730
- const code = line.slice(0, 2);
22731
- const file = line.slice(3);
22732
- if (code === "??") {
22733
- untracked.push(file);
22734
- } else {
22735
- if (code[0] !== " " && code[0] !== "?")
22736
- staged.push(file);
22737
- if (code[1] !== " " && code[1] !== "?")
22738
- unstaged.push(file);
22739
- }
22740
- }
22741
- const pathArgs = paths.length ? ["--", ...paths] : [];
22742
- const diff_stat = runHere(["diff", "--stat", ...pathArgs]);
22743
- const cached_stat = runHere(["diff", "--cached", "--stat", ...pathArgs]);
22744
- const stagedSet = new Set(staged);
22745
- const unstagedSet = new Set(unstaged);
22746
- const partial_staged = [...stagedSet].filter((f) => unstagedSet.has(f));
22747
- return {
22748
- workspace_root: cwd,
22749
- branch,
22750
- status_short,
22751
- staged,
22752
- unstaged,
22753
- untracked,
22754
- diff_stat: [diff_stat, cached_stat].filter(Boolean).join(`
22755
- `),
22756
- partial_staged: partial_staged.length > 0,
22757
- partial_staged_files: partial_staged,
22758
- ...failure ? { stderr: failure.stderr, exitCode: failure.exitCode } : {}
22759
- };
22760
- };
22694
+ // packages/workit-core/src/core/branch-policy.ts
22695
+ import { spawnSync as spawnSync7 } from "node:child_process";
22761
22696
 
22762
22697
  // packages/workit-core/src/core/config.ts
22763
22698
  import {
@@ -22883,6 +22818,7 @@ var DEFAULTS = {
22883
22818
  },
22884
22819
  commitPolicy: { preset: "conventional" }
22885
22820
  };
22821
+ var unchosenBranchPolicy = new WeakSet([DEFAULTS]);
22886
22822
  var readSafe = (p) => {
22887
22823
  try {
22888
22824
  return readFileSync3(p, "utf8");
@@ -22907,22 +22843,21 @@ var parseConfigResult = (raw, file) => {
22907
22843
  const locale = LOCALE_RE.test(String(input.locale ?? "")) ? input.locale : DEFAULTS.locale;
22908
22844
  const preset = Object.hasOwn(PRESETS, input.branchPolicy?.preset) ? input.branchPolicy?.preset : "gitflow";
22909
22845
  const commitPreset = COMMIT_PRESETS.includes(String(input.commitPolicy?.preset ?? "")) ? input.commitPolicy?.preset : "conventional";
22910
- return {
22911
- status: "valid",
22912
- path: file,
22913
- config: {
22914
- locale,
22915
- localeOptions: Array.isArray(input.localeOptions) ? input.localeOptions : DEFAULTS.localeOptions,
22916
- branchPolicy: mergePreset(preset, {
22917
- allowed: Array.isArray(input.branchPolicy?.allowed) ? input.branchPolicy.allowed : undefined,
22918
- protectedNames: Array.isArray(input.branchPolicy?.protected) ? input.branchPolicy.protected : undefined
22919
- }, DEFAULTS),
22920
- commitPolicy: {
22921
- preset: commitPreset,
22922
- ...typeof input.commitPolicy?.pattern === "string" ? { pattern: input.commitPolicy.pattern } : {}
22923
- }
22846
+ const config = {
22847
+ locale,
22848
+ localeOptions: Array.isArray(input.localeOptions) ? input.localeOptions : DEFAULTS.localeOptions,
22849
+ branchPolicy: mergePreset(preset, {
22850
+ allowed: Array.isArray(input.branchPolicy?.allowed) ? input.branchPolicy.allowed : undefined,
22851
+ protectedNames: Array.isArray(input.branchPolicy?.protected) ? input.branchPolicy.protected : undefined
22852
+ }, DEFAULTS),
22853
+ commitPolicy: {
22854
+ preset: commitPreset,
22855
+ ...typeof input.commitPolicy?.pattern === "string" ? { pattern: input.commitPolicy.pattern } : {}
22924
22856
  }
22925
22857
  };
22858
+ if (!Object.hasOwn(PRESETS, input.branchPolicy?.preset))
22859
+ unchosenBranchPolicy.add(config);
22860
+ return { status: "valid", path: file, config };
22926
22861
  };
22927
22862
  var readConfigTyped = (dir) => {
22928
22863
  const file = path12.join(dir ?? configDir(), "config.json");
@@ -22936,9 +22871,11 @@ var readConfig = () => {
22936
22871
  };
22937
22872
  var vcsConfigPath = () => process.env.WORKFLOW_VCS_CONFIG ?? path12.join(configDir(), "vcs.json");
22938
22873
  var branchGlobPattern = (glob) => new RegExp(`^${glob.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*")}$`, "i");
22939
- var resolveBranchPolicy = (config, workspace) => {
22874
+ var resolveBranchPolicy = (config, workspace, repoPreset) => {
22940
22875
  const wp = workspace?.branchPolicy ?? {};
22941
- const preset = Object.hasOwn(PRESETS, wp.preset) ? wp.preset : config.branchPolicy?.preset ?? "gitflow";
22876
+ const workspacePreset = Object.hasOwn(PRESETS, wp.preset);
22877
+ const detected = !workspacePreset && unchosenBranchPolicy.has(config) ? repoPreset?.() ?? null : null;
22878
+ const preset = workspacePreset ? wp.preset : detected ?? config.branchPolicy?.preset ?? "gitflow";
22942
22879
  const merged = mergePreset(preset, {
22943
22880
  allowed: wp.allowed,
22944
22881
  protectedNames: wp.protected
@@ -22947,9 +22884,10 @@ var resolveBranchPolicy = (config, workspace) => {
22947
22884
  return {
22948
22885
  preset,
22949
22886
  allowed,
22950
- protected: new Set(merged.protected.map((p) => p.toLowerCase())),
22887
+ protected: new Set([...merged.protected, ...detected ? PRESETS.gitflow.protected : []].map((p) => p.toLowerCase())),
22951
22888
  integration: wp.integration === "merge" ? "merge" : "pr",
22952
- defaultTargetBranch: preset === "github-flow" ? "main" : preset === "trunk-based" ? "master" : "develop"
22889
+ defaultTargetBranch: preset === "github-flow" ? "main" : preset === "trunk-based" ? "master" : "develop",
22890
+ detected: detected !== null
22953
22891
  };
22954
22892
  };
22955
22893
  var COMMIT_PRESETS = [
@@ -22961,7 +22899,140 @@ var COMMIT_PRESETS = [
22961
22899
  "auto"
22962
22900
  ];
22963
22901
 
22902
+ // packages/workit-core/src/core/branch-policy.ts
22903
+ var PREFIXES = {
22904
+ feature: "feature/*",
22905
+ bugfix: "bugfix/*",
22906
+ release: "release/*",
22907
+ hotfix: "hotfix/*"
22908
+ };
22909
+ var branchNames = (workspaceRoot) => {
22910
+ const r = spawnSync7("git", ["for-each-ref", "--format=%(refname)", "refs/heads", "refs/remotes/origin"], { cwd: workspaceRoot, encoding: "utf8" });
22911
+ if (r.status !== 0)
22912
+ return new Set;
22913
+ return new Set((r.stdout ?? "").split(`
22914
+ `).filter(Boolean).map((ref) => ref.startsWith("refs/heads/") ? ref.slice("refs/heads/".length) : ref.slice("refs/remotes/origin/".length)));
22915
+ };
22916
+ var detectBranchPolicy = (workspaceRoot) => {
22917
+ const names = branchNames(workspaceRoot);
22918
+ const develop = names.has("develop");
22919
+ const main = names.has("main");
22920
+ const master = names.has("master");
22921
+ const root = main ? "main" : master ? "master" : null;
22922
+ if (develop) {
22923
+ return {
22924
+ preset: "gitflow",
22925
+ developBranch: "develop",
22926
+ integration: "merge",
22927
+ protected: root ? [root, "develop"] : ["develop"],
22928
+ allowed: [...PRESETS.gitflow.allowed],
22929
+ prefixes: PREFIXES
22930
+ };
22931
+ }
22932
+ if (root === "main") {
22933
+ return {
22934
+ preset: "github-flow",
22935
+ developBranch: null,
22936
+ integration: "pr",
22937
+ protected: [root],
22938
+ allowed: ["*"],
22939
+ prefixes: PREFIXES
22940
+ };
22941
+ }
22942
+ if (root === "master") {
22943
+ return {
22944
+ preset: "trunk-based",
22945
+ developBranch: null,
22946
+ integration: "pr",
22947
+ protected: [root],
22948
+ allowed: ["*"],
22949
+ prefixes: PREFIXES
22950
+ };
22951
+ }
22952
+ return {
22953
+ preset: "gitflow",
22954
+ developBranch: null,
22955
+ integration: "merge",
22956
+ protected: [],
22957
+ allowed: [],
22958
+ prefixes: PREFIXES
22959
+ };
22960
+ };
22961
+ var repoBranchPreset = (workspaceRoot) => {
22962
+ const detected = detectBranchPolicy(workspaceRoot);
22963
+ return detected.developBranch || detected.allowed.length ? detected.preset : null;
22964
+ };
22965
+
22966
+ // packages/workit-core/src/core/git.ts
22967
+ import { execFileSync } from "node:child_process";
22968
+ var run = (cwd, args) => {
22969
+ try {
22970
+ const stdout = execFileSync("git", args, {
22971
+ cwd,
22972
+ encoding: "utf8",
22973
+ stdio: ["pipe", "pipe", "pipe"]
22974
+ });
22975
+ return { stdout: stdout.trimEnd(), stderr: "", exitCode: 0 };
22976
+ } catch (error) {
22977
+ const e = error;
22978
+ return {
22979
+ stdout: (e.stdout ?? "").trimEnd(),
22980
+ stderr: (e.stderr ?? "").trimEnd(),
22981
+ exitCode: e.status ?? 1
22982
+ };
22983
+ }
22984
+ };
22985
+ var gitContext = (workspaceRoot, paths = []) => {
22986
+ const cwd = workspaceRoot;
22987
+ let failure;
22988
+ const runHere = (args) => {
22989
+ const result = run(cwd, args);
22990
+ if (!failure && result.exitCode !== 0) {
22991
+ failure = { stderr: result.stderr, exitCode: result.exitCode };
22992
+ }
22993
+ return result.stdout;
22994
+ };
22995
+ const branch = runHere(["rev-parse", "--abbrev-ref", "HEAD"]) || "unknown";
22996
+ const status_short = runHere(["status", "--porcelain"]);
22997
+ const staged = [];
22998
+ const unstaged = [];
22999
+ const untracked = [];
23000
+ for (const line of status_short.split(`
23001
+ `).filter(Boolean)) {
23002
+ const code = line.slice(0, 2);
23003
+ const file = line.slice(3);
23004
+ if (code === "??") {
23005
+ untracked.push(file);
23006
+ } else {
23007
+ if (code[0] !== " " && code[0] !== "?")
23008
+ staged.push(file);
23009
+ if (code[1] !== " " && code[1] !== "?")
23010
+ unstaged.push(file);
23011
+ }
23012
+ }
23013
+ const pathArgs = paths.length ? ["--", ...paths] : [];
23014
+ const diff_stat = runHere(["diff", "--stat", ...pathArgs]);
23015
+ const cached_stat = runHere(["diff", "--cached", "--stat", ...pathArgs]);
23016
+ const stagedSet = new Set(staged);
23017
+ const unstagedSet = new Set(unstaged);
23018
+ const partial_staged = [...stagedSet].filter((f) => unstagedSet.has(f));
23019
+ return {
23020
+ workspace_root: cwd,
23021
+ branch,
23022
+ status_short,
23023
+ staged,
23024
+ unstaged,
23025
+ untracked,
23026
+ diff_stat: [diff_stat, cached_stat].filter(Boolean).join(`
23027
+ `),
23028
+ partial_staged: partial_staged.length > 0,
23029
+ partial_staged_files: partial_staged,
23030
+ ...failure ? { stderr: failure.stderr, exitCode: failure.exitCode } : {}
23031
+ };
23032
+ };
23033
+
22964
23034
  // packages/workit-core/src/core/workspaces.ts
23035
+ import { spawnSync as spawnSync8 } from "node:child_process";
22965
23036
  import { createHash as createHash8 } from "node:crypto";
22966
23037
  import { readFileSync as readFileSync4, realpathSync as realpathSync3 } from "node:fs";
22967
23038
  import path13 from "node:path";
@@ -23206,6 +23277,53 @@ var validateWorkspaceGlob = (glob) => {
23206
23277
  }
23207
23278
  return { ok: true };
23208
23279
  };
23280
+
23281
+ class WorkspaceConfigError extends Error {
23282
+ name = "WorkspaceConfigError";
23283
+ }
23284
+ var mainCheckouts = new Map;
23285
+ var mainCheckoutOf = (cwd) => {
23286
+ const cached = mainCheckouts.get(cwd);
23287
+ if (cached !== undefined)
23288
+ return cached;
23289
+ const env = { ...process.env };
23290
+ for (const name of ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "GIT_INDEX_FILE"])
23291
+ delete env[name];
23292
+ const git = (args) => {
23293
+ const run = spawnSync8("git", args, {
23294
+ cwd,
23295
+ env,
23296
+ encoding: "utf8",
23297
+ timeout: 5000,
23298
+ windowsHide: true
23299
+ });
23300
+ return run.status === 0 ? run.stdout : null;
23301
+ };
23302
+ let main = null;
23303
+ const dirs = git(["rev-parse", "--path-format=absolute", "--git-dir", "--git-common-dir"]);
23304
+ const [gitDir, common] = (dirs ?? "").trim().split(/\r?\n/u);
23305
+ if (gitDir && common && path13.resolve(gitDir) !== path13.resolve(common)) {
23306
+ const listed = /^worktree (.+)$/mu.exec(git(["worktree", "list", "--porcelain"]) ?? "")?.[1];
23307
+ main = listed?.trim() || (path13.basename(common) === ".git" ? path13.dirname(common) : common);
23308
+ }
23309
+ mainCheckouts.set(cwd, main);
23310
+ return main;
23311
+ };
23312
+ var matchingEntries = (cwd, entries) => {
23313
+ const match = (where) => {
23314
+ const targets = [where, realpathOf(where)].map((value) => value.replaceAll("\\", "/"));
23315
+ return entries.filter((entry) => {
23316
+ const glob = entry.glob.replaceAll("\\", "/");
23317
+ const canonical = canonicalGlob(glob);
23318
+ return targets.some((target) => matchWorkspace(glob, target) || canonical !== glob && matchWorkspace(canonical, target));
23319
+ });
23320
+ };
23321
+ const direct = match(cwd);
23322
+ if (direct.length)
23323
+ return direct;
23324
+ const main = mainCheckoutOf(cwd);
23325
+ return main ? match(main) : direct;
23326
+ };
23209
23327
  var realpathOf = (p) => {
23210
23328
  const real = realpathSync3.native ?? realpathSync3;
23211
23329
  try {
@@ -23230,43 +23348,29 @@ var selectWorkspaceMatch = (matches, cwd, workspaceName) => {
23230
23348
  if (named.length === 1)
23231
23349
  return named[0];
23232
23350
  if (named.length > 1)
23233
- throw new Error(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
23351
+ throw new WorkspaceConfigError(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
23234
23352
  if (matches.length > 0) {
23235
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
23353
+ throw new WorkspaceConfigError(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
23236
23354
  }
23237
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
23355
+ throw new WorkspaceConfigError(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
23238
23356
  }
23239
23357
  if (matches.length < 2)
23240
23358
  return matches[0];
23241
23359
  const highestSpecificity = Math.max(...matches.map((entry) => globSpecificity(entry.glob)));
23242
23360
  const mostSpecific = matches.filter((entry) => globSpecificity(entry.glob) === highestSpecificity);
23243
23361
  if (mostSpecific.length > 1) {
23244
- throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${mostSpecific.map((entry) => entry.name).join(", ")}`);
23362
+ throw new WorkspaceConfigError(`ambiguous workspace for ${cwd}; choose one of: ${mostSpecific.map((entry) => entry.name).join(", ")}`);
23245
23363
  }
23246
23364
  return mostSpecific[0];
23247
23365
  };
23248
23366
  var resolveWorkspaceFromEntries = (cwd, entries, workspaceName) => {
23249
- const targets = [cwd, realpathOf(cwd)].map((p) => p.replaceAll("\\", "/"));
23250
- const matches = [];
23251
- for (const ws of entries) {
23252
- const glob = ws.glob.replaceAll("\\", "/");
23253
- const canonical = canonicalGlob(glob);
23254
- let matched = false;
23255
- for (const target of targets) {
23256
- if (matchWorkspace(glob, target) || canonical !== glob && matchWorkspace(canonical, target)) {
23257
- matched = true;
23258
- break;
23259
- }
23260
- }
23261
- if (matched)
23262
- matches.push(ws);
23263
- }
23367
+ const matches = matchingEntries(cwd, entries);
23264
23368
  return selectWorkspaceMatch(matches, cwd, workspaceName) ?? null;
23265
23369
  };
23266
23370
  var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
23267
23371
  const result = readWorkspacesResult(dir);
23268
23372
  if (result.status === "malformed" || result.status === "invalid")
23269
- throw new Error(result.error);
23373
+ throw new WorkspaceConfigError(result.error);
23270
23374
  return resolveWorkspaceFromEntries(cwd, result.entries, workspaceName);
23271
23375
  };
23272
23376
  var runtimeWorkspacePolicySchema = (kind) => {
@@ -23298,31 +23402,26 @@ var matchRuntimeWorkspace = (cwd) => {
23298
23402
  } catch (error) {
23299
23403
  if (error.code === "ENOENT")
23300
23404
  return null;
23301
- throw new Error(`${file} could not be read: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
23405
+ throw new WorkspaceConfigError(`${file} could not be read: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
23302
23406
  }
23303
23407
  let parsed;
23304
23408
  try {
23305
23409
  parsed = JSON.parse(raw);
23306
23410
  } catch {
23307
- throw new Error(`${file} is not valid JSON`);
23411
+ throw new WorkspaceConfigError(`${file} is not valid JSON`);
23308
23412
  }
23309
23413
  const validated = runtimeWorkspaceIndexSchema.safeParse(parsed);
23310
23414
  if (!validated.success) {
23311
23415
  const detail = validated.error.issues.map((issue) => `${issue.path.map(String).join(".") || "workspaces"}: ${issue.message}`).join("; ");
23312
- throw new Error(`${file} has invalid workspace matching data: ${detail}`);
23416
+ throw new WorkspaceConfigError(`${file} has invalid workspace matching data: ${detail}`);
23313
23417
  }
23314
23418
  const entries = validated.data.workspaces;
23315
23419
  for (const entry of entries ?? []) {
23316
23420
  const glob = validateWorkspaceGlob(entry.glob);
23317
23421
  if (!glob.ok)
23318
- throw new Error(`${file} workspace ${entry.name}: ${glob.error}`);
23422
+ throw new WorkspaceConfigError(`${file} workspace ${entry.name}: ${glob.error}`);
23319
23423
  }
23320
- const targets = [cwd, realpathOf(cwd)].map((value) => value.replaceAll("\\", "/"));
23321
- const matches = (entries ?? []).filter((entry) => {
23322
- const glob = entry.glob.replaceAll("\\", "/");
23323
- const canonical = canonicalGlob(glob);
23324
- return targets.some((target) => matchWorkspace(glob, target) || canonical !== glob && matchWorkspace(canonical, target));
23325
- });
23424
+ const matches = matchingEntries(cwd, entries ?? []);
23326
23425
  const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
23327
23426
  const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
23328
23427
  return selected ? { file, selected } : null;
@@ -23339,7 +23438,7 @@ var resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
23339
23438
  const policy = runtimeWorkspacePolicySchema(kind).safeParse(selected);
23340
23439
  if (!policy.success) {
23341
23440
  const detail = policy.error.issues.map((issue) => `${issue.path.map(String).join(".") || "workspace"}: ${issue.message}`).join("; ");
23342
- throw new Error(`${file} has invalid ${kind} policy configuration: ${detail}`);
23441
+ throw new WorkspaceConfigError(`${file} has invalid ${kind} policy configuration: ${detail}`);
23343
23442
  }
23344
23443
  return policy.data;
23345
23444
  };
@@ -23350,10 +23449,10 @@ var resolveRuntimeWorkspacePolicy = (cwd, kind, requestedProfile) => {
23350
23449
  const key = kind === "branch" ? "branchPolicy" : "commitPolicy";
23351
23450
  const profileName = requestedProfile?.trim() || candidate.defaultProfile;
23352
23451
  if (candidate.defaultProfile && !Object.hasOwn(candidate.profiles ?? {}, candidate.defaultProfile))
23353
- throw new Error(`workspace ${JSON.stringify(candidate.name)} has no profile ${JSON.stringify(candidate.defaultProfile)}`);
23452
+ throw new WorkspaceConfigError(`workspace ${JSON.stringify(candidate.name)} has no profile ${JSON.stringify(candidate.defaultProfile)}`);
23354
23453
  const profile = profileName ? candidate.profiles?.[profileName] : undefined;
23355
23454
  if (profileName && !profile)
23356
- throw new Error(`workspace ${JSON.stringify(candidate.name)} has no profile ${JSON.stringify(profileName)}`);
23455
+ throw new WorkspaceConfigError(`workspace ${JSON.stringify(candidate.name)} has no profile ${JSON.stringify(profileName)}`);
23357
23456
  const profilePolicy = profile?.[key];
23358
23457
  const workspacePolicy = candidate[key];
23359
23458
  return {
@@ -23366,18 +23465,18 @@ function workspaceDefaultTarget(cwd, globalDefault) {
23366
23465
  const wp = ws?.branchPolicy ?? {};
23367
23466
  const hasWorkspacePolicy = typeof wp.preset === "string" && Object.hasOwn(PRESETS, wp.preset);
23368
23467
  const selected = resolveRuntimeWorkspacePolicy(cwd, "branch", process.env.WORKFLOW_PROFILE?.trim() || undefined);
23369
- const policyDefault = resolveBranchPolicy(readConfig(), selected.policy ? { branchPolicy: selected.policy } : null).defaultTargetBranch;
23468
+ const policyDefault = resolveBranchPolicy(readConfig(), selected.policy ? { branchPolicy: selected.policy } : null, () => repoBranchPreset(cwd)).defaultTargetBranch;
23370
23469
  return String(ws?.vcs?.defaultTargetBranch ?? (hasWorkspacePolicy ? policyDefault : globalDefault ?? policyDefault) ?? "develop");
23371
23470
  }
23372
23471
 
23373
23472
  // packages/workit-core/src/core/vcs-config.ts
23374
23473
  import fs12 from "node:fs";
23375
23474
  import path14 from "node:path";
23376
- import { spawnSync as spawnSync8 } from "node:child_process";
23475
+ import { spawnSync as spawnSync10 } from "node:child_process";
23377
23476
 
23378
23477
  // packages/workit-core/src/core/release-tracks.ts
23379
23478
  import { createHash as createHash9 } from "node:crypto";
23380
- import { spawnSync as spawnSync7 } from "node:child_process";
23479
+ import { spawnSync as spawnSync9 } from "node:child_process";
23381
23480
  var KNOWN_FIELDS = new Set([
23382
23481
  "strategy",
23383
23482
  "productionBranch",
@@ -23649,7 +23748,7 @@ function resolveReleaseTrack(input) {
23649
23748
  return fallback(`${branch} has the same or unrelated fork points with ${[...new Set(newest.map((fork) => `${fork.ref} (${fork.track.name === IMPLICIT ? "workspace default" : fork.track.name})`))].join(" and ")}`);
23650
23749
  }
23651
23750
  var git4 = (cwd, args) => {
23652
- const run = spawnSync7("git", args, {
23751
+ const run = spawnSync9("git", args, {
23653
23752
  cwd,
23654
23753
  encoding: "utf8",
23655
23754
  timeout: 20000,
@@ -23764,7 +23863,7 @@ function resolveTrackFor(cwd, options) {
23764
23863
  var workspacesPath = () => path14.join(configDir(), "workspaces.json");
23765
23864
  var vcsCwd = (cwd) => cwd ?? process.env.WORKFLOW_WORKSPACE_ROOT ?? process.cwd();
23766
23865
  var remoteProvider = (cwd) => {
23767
- const r = spawnSync8("git", ["remote", "get-url", "origin"], { cwd, encoding: "utf8" });
23866
+ const r = spawnSync10("git", ["remote", "get-url", "origin"], { cwd, encoding: "utf8" });
23768
23867
  if (r.status !== 0)
23769
23868
  return null;
23770
23869
  const url = (r.stdout ?? "").trim();
@@ -23801,7 +23900,7 @@ var remoteEndpoint = (remote) => {
23801
23900
  var configuredSshEndpoint = (host) => {
23802
23901
  if (host.startsWith("-"))
23803
23902
  return null;
23804
- const resolved = spawnSync8("ssh", ["-G", host], {
23903
+ const resolved = spawnSync10("ssh", ["-G", host], {
23805
23904
  encoding: "utf8",
23806
23905
  timeout: 5000,
23807
23906
  maxBuffer: 1024 * 1024,
@@ -23974,7 +24073,7 @@ function mergedPrStyle(limit = 6, cwd) {
23974
24073
  `).filter((l) => l.startsWith("## ")).map((l) => l.trim()),
23975
24074
  descriptionPreview: desc.slice(0, 600)
23976
24075
  });
23977
- const remoteResult = spawnSync8("git", ["remote", "get-url", "--push", "--all", "origin"], {
24076
+ const remoteResult = spawnSync10("git", ["remote", "get-url", "--push", "--all", "origin"], {
23978
24077
  cwd,
23979
24078
  encoding: "utf8"
23980
24079
  });
@@ -23990,7 +24089,7 @@ function mergedPrStyle(limit = 6, cwd) {
23990
24089
  if (!hostingApiHostMatches(remote, host))
23991
24090
  return { ok: false, error: "PR style target does not match the provider host" };
23992
24091
  if (provider === "gitlab") {
23993
- const run = (args) => spawnSync8("glab", ["api", ...args], {
24092
+ const run = (args) => spawnSync10("glab", ["api", ...args], {
23994
24093
  cwd,
23995
24094
  encoding: "utf8",
23996
24095
  env
@@ -24010,7 +24109,7 @@ function mergedPrStyle(limit = 6, cwd) {
24010
24109
  });
24011
24110
  }
24012
24111
  } else if (provider === "github") {
24013
- const r = spawnSync8("gh", [
24112
+ const r = spawnSync10("gh", [
24014
24113
  "pr",
24015
24114
  "list",
24016
24115
  "--repo",
@@ -25947,7 +26046,7 @@ class WorkitCore {
25947
26046
  }
25948
26047
  }
25949
26048
  // packages/workit-core/src/core/repo-context.ts
25950
- import { spawnSync as spawnSync9 } from "node:child_process";
26049
+ import { spawnSync as spawnSync11 } from "node:child_process";
25951
26050
  import { existsSync as existsSync6, readFileSync as readFileSync5, readdirSync as readdirSync4 } from "node:fs";
25952
26051
  import path16 from "node:path";
25953
26052
  var isSafeContextRange = (value) => value.length <= 4096 && (() => {
@@ -25976,7 +26075,7 @@ var invalidRange = (cwd) => ({
25976
26075
  cwd
25977
26076
  });
25978
26077
  var runGit = (cwd, args) => {
25979
- const result = spawnSync9("git", args, { cwd, encoding: "utf8" });
26078
+ const result = spawnSync11("git", args, { cwd, encoding: "utf8" });
25980
26079
  return {
25981
26080
  stdout: (result.stdout ?? "").trimEnd(),
25982
26081
  stderr: (result.stderr ?? "").trimEnd(),
@@ -26417,12 +26516,12 @@ function releaseNotesContext(root, rangeOrTag) {
26417
26516
  }
26418
26517
 
26419
26518
  // packages/workit-core/src/core/tracker-issues.ts
26420
- import { spawnSync as spawnSync11 } from "node:child_process";
26519
+ import { spawnSync as spawnSync13 } from "node:child_process";
26421
26520
 
26422
26521
  // packages/workit-core/src/core/pr-create.ts
26423
26522
  import fs13 from "node:fs";
26424
26523
  import path17 from "node:path";
26425
- import { spawnSync as spawnSync10 } from "node:child_process";
26524
+ import { spawnSync as spawnSync12 } from "node:child_process";
26426
26525
  // packages/workit-core/src/forge/pr-body.ts
26427
26526
  function parseGhIssue(value) {
26428
26527
  const m = /issues\/(\d+)/.exec(value);
@@ -26447,7 +26546,7 @@ function whichOnPath(tool) {
26447
26546
  }
26448
26547
  var hostingCliAvailable = (provider) => whichOnPath(provider === "gitlab" ? "glab" : "gh") !== null;
26449
26548
  var pushRemote = (cwd) => {
26450
- const result = spawnSync10("git", ["remote", "get-url", "--push", "--all", "origin"], {
26549
+ const result = spawnSync12("git", ["remote", "get-url", "--push", "--all", "origin"], {
26451
26550
  cwd,
26452
26551
  encoding: "utf8"
26453
26552
  });
@@ -26478,7 +26577,7 @@ var defaultCli = (bin, available) => {
26478
26577
  if (!available)
26479
26578
  return null;
26480
26579
  return (args, root) => {
26481
- const out = spawnSync11(bin, args, {
26580
+ const out = spawnSync13(bin, args, {
26482
26581
  cwd: root,
26483
26582
  encoding: "utf8",
26484
26583
  env: { ...process.env, PATH: process.env.PATH ?? "" }
@@ -26996,7 +27095,7 @@ function resolveInside(root, candidate) {
26996
27095
  }
26997
27096
  function run2(root, executable, args, env = {}) {
26998
27097
  const cwd = realpathSync5(root);
26999
- const result = spawnSync12(executable, args, {
27098
+ const result = spawnSync14(executable, args, {
27000
27099
  cwd,
27001
27100
  encoding: "utf8",
27002
27101
  env: { ...process.env, ...env }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-mcp",
3
- "version": "8.0.1",
3
+ "version": "8.1.1",
4
4
  "private": false,
5
5
  "description": "Workit shared MCP transport for the eight task and policy operation families",
6
6
  "keywords": [
@@ -42,7 +42,7 @@
42
42
  "build": "bun scripts/build.ts"
43
43
  },
44
44
  "dependencies": {
45
- "@brainervirus/workit-core": "^8.0.1",
45
+ "@brainervirus/workit-core": "^8.1.1",
46
46
  "@modelcontextprotocol/sdk": "1.32.0",
47
47
  "zod": "4.6.5"
48
48
  },