@brainervirus/workit-cli 1.3.0 → 1.3.2

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 +35 -39
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -49970,6 +49970,28 @@ var canonicalGlob = (glob) => {
49970
49970
  const real = realpathOf(prefix.replace(/\/+$/, "") || "/");
49971
49971
  return real + (prefix.endsWith("/") ? "/" : "") + rest;
49972
49972
  };
49973
+ var globSpecificity = (glob) => glob.replaceAll("\\", "/").split("/").filter((segment) => segment.length > 0 && !/[*?[\]{]/.test(segment)).length;
49974
+ var selectWorkspaceMatch = (matches, cwd, workspaceName) => {
49975
+ if (workspaceName !== undefined) {
49976
+ const named = matches.filter((entry) => entry.name === workspaceName);
49977
+ if (named.length === 1)
49978
+ return named[0];
49979
+ if (named.length > 1)
49980
+ throw new Error(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
49981
+ if (matches.length > 0) {
49982
+ throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
49983
+ }
49984
+ throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
49985
+ }
49986
+ if (matches.length < 2)
49987
+ return matches[0];
49988
+ const highestSpecificity = Math.max(...matches.map((entry) => globSpecificity(entry.glob)));
49989
+ const mostSpecific = matches.filter((entry) => globSpecificity(entry.glob) === highestSpecificity);
49990
+ if (mostSpecific.length > 1) {
49991
+ throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${mostSpecific.map((entry) => entry.name).join(", ")}`);
49992
+ }
49993
+ return mostSpecific[0];
49994
+ };
49973
49995
  var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
49974
49996
  const result = readWorkspacesResult(dir);
49975
49997
  if (result.status === "malformed" || result.status === "invalid")
@@ -49989,20 +50011,7 @@ var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
49989
50011
  if (matched)
49990
50012
  matches.push(ws);
49991
50013
  }
49992
- if (workspaceName !== undefined) {
49993
- const selected = matches.find((ws) => ws.name === workspaceName);
49994
- if (!selected && matches.length > 0) {
49995
- const matchingNames = matches.map((ws) => ws.name);
49996
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matchingNames.join(", ")}`);
49997
- }
49998
- if (selected)
49999
- return selected;
50000
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
50001
- }
50002
- if (matches.length > 1) {
50003
- throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${matches.map((ws) => ws.name).join(", ")}`);
50004
- }
50005
- return matches[0] ?? null;
50014
+ return selectWorkspaceMatch(matches, cwd, workspaceName) ?? null;
50006
50015
  };
50007
50016
  var runtimeWorkspacePolicySchema = (kind) => {
50008
50017
  const key = kind === "branch" ? "branchPolicy" : kind === "commit" ? "commitPolicy" : "vcs";
@@ -50059,21 +50068,7 @@ var resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
50059
50068
  return targets.some((target) => matchWorkspace(glob, target) || canonical !== glob && matchWorkspace(canonical, target));
50060
50069
  });
50061
50070
  const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
50062
- let selected;
50063
- if (workspaceName) {
50064
- const named = matches.filter((entry) => entry.name === workspaceName);
50065
- if (named.length === 1)
50066
- selected = named[0];
50067
- else if (named.length > 1)
50068
- throw new Error(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
50069
- else if (matches.length)
50070
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
50071
- else
50072
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
50073
- } else if (matches.length > 1)
50074
- throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${matches.map((entry) => entry.name).join(", ")}`);
50075
- else
50076
- selected = matches[0];
50071
+ const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
50077
50072
  if (!selected)
50078
50073
  return null;
50079
50074
  const policy = runtimeWorkspacePolicySchema(kind).safeParse(selected);
@@ -60543,7 +60538,7 @@ var branchSetup = ({
60543
60538
  const dirty = Boolean(gitContext(cwd).status_short.trim());
60544
60539
  if (classifyBranchDirt(cwd) === "stash-required" && stash !== "yes") {
60545
60540
  return {
60546
- error: "dirty working tree — ask with native question, then call workit_branch_setup with stash=yes",
60541
+ error: "dirty working tree — obtain native host approval before stashing and setting up the branch",
60547
60542
  phase: "preflight"
60548
60543
  };
60549
60544
  }
@@ -62910,6 +62905,7 @@ function resolveRequirements(input) {
62910
62905
  dependentAction: null,
62911
62906
  acceptanceAllowed: false
62912
62907
  }));
62908
+ const independentBehaviorReview = input.preferences?.thorough === true || input.assessment.consequences.some((consequence) => ["security", "data", "public_contract", "operations"].includes(consequence.area));
62913
62909
  if (signals.behaviorChange.value === true)
62914
62910
  requirements.push(requirement({
62915
62911
  ruleId: "behavioral-verification",
@@ -62921,14 +62917,14 @@ function resolveRequirements(input) {
62921
62917
  dependentAction: null,
62922
62918
  acceptanceAllowed: false
62923
62919
  }), requirement({
62924
- ruleId: "fresh-context-review",
62920
+ ruleId: independentBehaviorReview ? "fresh-context-review" : "self-review",
62925
62921
  dimension: "review",
62926
62922
  scope,
62927
- reason: "A non-mechanical behavior change requires fresh-context review.",
62928
- satisfaction: "A separate review context examines the current candidate and records its result.",
62923
+ reason: independentBehaviorReview ? "Consequential behavior or the thorough preference requires fresh-context review." : "Bounded behavior changes use self-review unless consequential risks or trusted rules require more.",
62924
+ satisfaction: independentBehaviorReview ? "A separate review context examines the current candidate and records its result." : "The lead reviews the resulting diff and records the relevant scope and checks.",
62929
62925
  before: "close",
62930
62926
  dependentAction: null,
62931
- acceptanceAllowed: false
62927
+ acceptanceAllowed: !independentBehaviorReview
62932
62928
  }));
62933
62929
  else if (signals.mechanicalLowRisk.value === true)
62934
62930
  requirements.push(requirement({
@@ -65949,7 +65945,7 @@ var CHANGELOG_RULES = `- Use an [Unreleased] section.
65949
65945
  - Entries should be human-readable and user-facing.
65950
65946
  - Do not use raw commit messages as changelog bullets.
65951
65947
  - MERGE into existing ### Category under [Unreleased] — never append a second ### Added / ### Fixed block.
65952
- - Apply with the native workit_changelog_apply tool only (not hand-edits under Unreleased).
65948
+ - Apply with the host-native editor, preserving the repository changelog conventions.
65953
65949
  - If Unreleased already has duplicate category headings, normalize_only first.`;
65954
65950
  function changelogContext(root, range) {
65955
65951
  const cwd = path29.resolve(repoRoot3(root));
@@ -66735,7 +66731,7 @@ async function postUpdate({
66735
66731
  postedComment: true,
66736
66732
  loggedMinutes: 0,
66737
66733
  error: time.error,
66738
- retry: "workit_youtrack_log_time"
66734
+ retry: "youtrack.time"
66739
66735
  };
66740
66736
  }
66741
66737
  return { ok: true, issueId, postedComment: true, loggedMinutes: minutes };
@@ -66785,7 +66781,7 @@ async function postUpdate2(input, operations = defaultOperations) {
66785
66781
  postedComment: false,
66786
66782
  loggedMinutes: 0,
66787
66783
  outcome: "not_applied",
66788
- retry: "workit_youtrack_post"
66784
+ retry: "youtrack.update"
66789
66785
  });
66790
66786
  unwrap(comment);
66791
66787
  } catch (error) {
@@ -66812,7 +66808,7 @@ async function postUpdate2(input, operations = defaultOperations) {
66812
66808
  postedComment: true,
66813
66809
  loggedMinutes: 0,
66814
66810
  outcome: "not_applied",
66815
- retry: "workit_youtrack_log_time"
66811
+ retry: "youtrack.time"
66816
66812
  });
66817
66813
  unwrap(time);
66818
66814
  } catch (error) {
@@ -66839,7 +66835,7 @@ async function logTimeUpdate(input, operation = defaultOperations) {
66839
66835
  issueId: input.issueId,
66840
66836
  loggedMinutes: 0,
66841
66837
  outcome: "not_applied",
66842
- retry: "workit_youtrack_log_time"
66838
+ retry: "youtrack.time"
66843
66839
  });
66844
66840
  return ok(unwrap(value));
66845
66841
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "private": false,
5
5
  "description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
6
6
  "keywords": [
@@ -37,9 +37,9 @@
37
37
  "typecheck": "tsc --noEmit"
38
38
  },
39
39
  "dependencies": {
40
- "@brainervirus/workit-core": "^1.3.0",
41
- "@brainervirus/workit-cursor": "^1.3.0",
42
- "@brainervirus/workit-opencode": "^1.3.0",
40
+ "@brainervirus/workit-core": "^1.3.2",
41
+ "@brainervirus/workit-cursor": "^1.3.2",
42
+ "@brainervirus/workit-opencode": "^1.3.2",
43
43
  "@inkjs/ui": "2.0.0",
44
44
  "ink": "7.1.1",
45
45
  "react": "19.2.8"