@brainervirus/workit-cursor 8.21.2 → 8.22.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.
@@ -2,7 +2,7 @@
2
2
  "name": "workit",
3
3
  "displayName": "Workit",
4
4
  "description": "Adaptive Workit workflow with shared MCP tools and native Cursor hooks",
5
- "version": "8.21.2",
5
+ "version": "8.22.0",
6
6
  "author": {
7
7
  "name": "Cristhofer Pincetti"
8
8
  },
@@ -16319,6 +16319,9 @@ Autonomy contract:
16319
16319
  CLI first: if a step has one right answer, use the \`workit\` verb instead of
16320
16320
  hand-running git, gh or glab (\`workit git|pr|ci|check|help\`;
16321
16321
  else \`npx -y @brainervirus/workit-cli\`).
16322
+ Other checkout: \`workit --cwd <dir> <verb>\` (Codex: \`<verb> --cwd <dir>\`); one workit
16323
+ verb per shell call, never \`cd <dir> && workit\`. zsh-safe: no \`echo =====\`
16324
+ (\`printf '%s\\n' ---\`), quote globs and URLs, no variable named \`status\` or \`path\`.
16322
16325
  Add Co-Authored-By via \`workit git commit --trailer "K: v" -- <paths>\`, never
16323
16326
  an amend.
16324
16327
  The task families (task, policy, evidence, finding, decision, worker, state)
@@ -22351,6 +22354,42 @@ var init_standing = __esm(() => {
22351
22354
  sinceStart = new Map;
22352
22355
  });
22353
22356
 
22357
+ // packages/workit-core/src/hooks/cwd-normalize.ts
22358
+ var COMPOUND, FILTERS, stdinOnly = (words) => {
22359
+ const [name, ...args] = words;
22360
+ const operands = args.filter((w) => !w.startsWith("-"));
22361
+ if (name === "grep")
22362
+ return operands.length <= 1 && !args.some((w) => /^-[^-]*[rRf]|^--(recursive|file)/u.test(w));
22363
+ return operands.every((w) => /^\d+$/u.test(w)) && !args.some((w) => w.startsWith("--output"));
22364
+ }, cwdRewrite = (command) => {
22365
+ const match = COMPOUND.exec(command);
22366
+ const dir = match?.[1];
22367
+ const rest = match?.[2];
22368
+ if (!dir || !rest || dir.startsWith("-"))
22369
+ return null;
22370
+ if (/[&;<>`\n]/u.test(rest.replaceAll("2>&1", "")))
22371
+ return null;
22372
+ const segments = segmentsOf(rest);
22373
+ const [head, ...filters] = segments;
22374
+ if (!head || head.words[0] !== "workit")
22375
+ return null;
22376
+ if (head.words.some((w) => w === "--cwd" || w.startsWith("--cwd=")))
22377
+ return null;
22378
+ const clean = (s) => !s.unanalyzable && !s.group && !s.subs?.length && !s.stdin?.length && !s.redirects.length;
22379
+ if (!segments.every(clean))
22380
+ return null;
22381
+ if (!segments.slice(0, -1).every((s) => s.pipe))
22382
+ return null;
22383
+ if (!filters.every((s) => FILTERS.has(s.words[0] ?? "") && stdinOnly(s.words)))
22384
+ return null;
22385
+ return `workit --cwd ${dir} ${rest.slice("workit".length).trimStart()}`.trimEnd();
22386
+ };
22387
+ var init_cwd_normalize = __esm(() => {
22388
+ init_shell_words();
22389
+ COMPOUND = /^\s*cd\s+([A-Za-z0-9_./@%+:,=-]+|'[^'$`\\\n]*'|"[^"$`\\!\n]*")\s*&&\s*(workit(?:\s[\s\S]*)?)$/u;
22390
+ FILTERS = new Set(["tail", "head", "grep"]);
22391
+ });
22392
+
22354
22393
  // packages/workit-core/src/hooks/handle.ts
22355
22394
  function handleHook(input, deps) {
22356
22395
  const decision = decide(input, deps);
@@ -22416,19 +22455,21 @@ function decide(input, deps) {
22416
22455
  if (plan.kind === "rewrite" && !rewrites && canDeny)
22417
22456
  return heavyDenial(event.command, plan);
22418
22457
  const lease = plan.kind === "rewrite" && rewrites ? plan : null;
22458
+ const cwdCommand = !lease && rewrites && input.host === "claude_code" ? cwdRewrite(event.command) : null;
22419
22459
  const aside = plan.kind === "passthrough" ? plan.note : null;
22420
22460
  noteRawCommit(input, event.command, postTool ? callKey(event.toolUseId, event.command) : NEXT_COMMAND);
22421
- const rewritten = (text) => lease ? {
22461
+ const rewrittenTo = lease?.command ?? cwdCommand;
22462
+ const rewritten = (text) => rewrittenTo ? {
22422
22463
  kind: "rewrite",
22423
- command: lease.command,
22424
- input: event.toolInput ? { ...event.toolInput, command: lease.command } : null,
22464
+ command: rewrittenTo,
22465
+ input: event.toolInput ? { ...event.toolInput, command: rewrittenTo } : null,
22425
22466
  text
22426
22467
  } : NONE5;
22427
22468
  if (descriptor.transport !== "hook-process")
22428
22469
  return rewritten(null);
22429
22470
  const nudged = withContextLine(withContextLine(canDeny ? rawGitPre(input, event.command) : NONE5, aside), shipNudge(input, event.command));
22430
22471
  if (!lease)
22431
- return nudged;
22472
+ return cwdCommand && nudged.kind !== "deny" ? rewritten(nudged.kind === "context" ? nudged.text : null) : nudged;
22432
22473
  return rewritten([rewriteNote(lease), nudged.kind === "context" ? nudged.text : null].filter(Boolean).join(`
22433
22474
  `));
22434
22475
  }
@@ -22522,6 +22563,7 @@ var init_handle = __esm(() => {
22522
22563
  init_branch();
22523
22564
  init_workspaces();
22524
22565
  init_host_session();
22566
+ init_cwd_normalize();
22525
22567
  init_heavy_gate();
22526
22568
  init_policy();
22527
22569
  init_raw_git();
@@ -28839,6 +28839,9 @@ var WRITE_TOOLS = new Set([
28839
28839
  ]);
28840
28840
  // packages/workit-core/src/hooks/standing.ts
28841
28841
  var sinceStart = new Map;
28842
+ // packages/workit-core/src/hooks/cwd-normalize.ts
28843
+ var FILTERS = new Set(["tail", "head", "grep"]);
28844
+
28842
28845
  // packages/workit-core/src/hooks/handle.ts
28843
28846
  var offered = new Set;
28844
28847
  var PRE_TOOL = new Set(["shell.pre", "write.pre", "tool.pre"]);
@@ -16399,6 +16399,9 @@ Autonomy contract:
16399
16399
  CLI first: if a step has one right answer, use the \`workit\` verb instead of
16400
16400
  hand-running git, gh or glab (\`workit git|pr|ci|check|help\`;
16401
16401
  else \`npx -y @brainervirus/workit-cli\`).
16402
+ Other checkout: \`workit --cwd <dir> <verb>\` (Codex: \`<verb> --cwd <dir>\`); one workit
16403
+ verb per shell call, never \`cd <dir> && workit\`. zsh-safe: no \`echo =====\`
16404
+ (\`printf '%s\\n' ---\`), quote globs and URLs, no variable named \`status\` or \`path\`.
16402
16405
  Add Co-Authored-By via \`workit git commit --trailer "K: v" -- <paths>\`, never
16403
16406
  an amend.
16404
16407
  The task families (task, policy, evidence, finding, decision, worker, state)
@@ -22593,6 +22596,40 @@ var standingDelta = (input) => {
22593
22596
  }
22594
22597
  };
22595
22598
  var sinceStart = new Map;
22599
+ // packages/workit-core/src/hooks/cwd-normalize.ts
22600
+ var COMPOUND = /^\s*cd\s+([A-Za-z0-9_./@%+:,=-]+|'[^'$`\\\n]*'|"[^"$`\\!\n]*")\s*&&\s*(workit(?:\s[\s\S]*)?)$/u;
22601
+ var FILTERS = new Set(["tail", "head", "grep"]);
22602
+ var stdinOnly = (words) => {
22603
+ const [name, ...args] = words;
22604
+ const operands = args.filter((w) => !w.startsWith("-"));
22605
+ if (name === "grep")
22606
+ return operands.length <= 1 && !args.some((w) => /^-[^-]*[rRf]|^--(recursive|file)/u.test(w));
22607
+ return operands.every((w) => /^\d+$/u.test(w)) && !args.some((w) => w.startsWith("--output"));
22608
+ };
22609
+ var cwdRewrite = (command) => {
22610
+ const match = COMPOUND.exec(command);
22611
+ const dir = match?.[1];
22612
+ const rest = match?.[2];
22613
+ if (!dir || !rest || dir.startsWith("-"))
22614
+ return null;
22615
+ if (/[&;<>`\n]/u.test(rest.replaceAll("2>&1", "")))
22616
+ return null;
22617
+ const segments = segmentsOf(rest);
22618
+ const [head, ...filters] = segments;
22619
+ if (!head || head.words[0] !== "workit")
22620
+ return null;
22621
+ if (head.words.some((w) => w === "--cwd" || w.startsWith("--cwd=")))
22622
+ return null;
22623
+ const clean = (s) => !s.unanalyzable && !s.group && !s.subs?.length && !s.stdin?.length && !s.redirects.length;
22624
+ if (!segments.every(clean))
22625
+ return null;
22626
+ if (!segments.slice(0, -1).every((s) => s.pipe))
22627
+ return null;
22628
+ if (!filters.every((s) => FILTERS.has(s.words[0] ?? "") && stdinOnly(s.words)))
22629
+ return null;
22630
+ return `workit --cwd ${dir} ${rest.slice("workit".length).trimStart()}`.trimEnd();
22631
+ };
22632
+
22596
22633
  // packages/workit-core/src/hooks/handle.ts
22597
22634
  var usable2 = (value) => value === "native" || value === "partial";
22598
22635
  var NONE5 = { kind: "none" };
@@ -22702,19 +22739,21 @@ function decide(input, deps) {
22702
22739
  if (plan.kind === "rewrite" && !rewrites && canDeny)
22703
22740
  return heavyDenial(event.command, plan);
22704
22741
  const lease = plan.kind === "rewrite" && rewrites ? plan : null;
22742
+ const cwdCommand = !lease && rewrites && input.host === "claude_code" ? cwdRewrite(event.command) : null;
22705
22743
  const aside = plan.kind === "passthrough" ? plan.note : null;
22706
22744
  noteRawCommit(input, event.command, postTool ? callKey(event.toolUseId, event.command) : NEXT_COMMAND);
22707
- const rewritten = (text) => lease ? {
22745
+ const rewrittenTo = lease?.command ?? cwdCommand;
22746
+ const rewritten = (text) => rewrittenTo ? {
22708
22747
  kind: "rewrite",
22709
- command: lease.command,
22710
- input: event.toolInput ? { ...event.toolInput, command: lease.command } : null,
22748
+ command: rewrittenTo,
22749
+ input: event.toolInput ? { ...event.toolInput, command: rewrittenTo } : null,
22711
22750
  text
22712
22751
  } : NONE5;
22713
22752
  if (descriptor.transport !== "hook-process")
22714
22753
  return rewritten(null);
22715
22754
  const nudged = withContextLine(withContextLine(canDeny ? rawGitPre(input, event.command) : NONE5, aside), shipNudge(input, event.command));
22716
22755
  if (!lease)
22717
- return nudged;
22756
+ return cwdCommand && nudged.kind !== "deny" ? rewritten(nudged.kind === "context" ? nudged.text : null) : nudged;
22718
22757
  return rewritten([rewriteNote(lease), nudged.kind === "context" ? nudged.text : null].filter(Boolean).join(`
22719
22758
  `));
22720
22759
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cursor",
3
- "version": "8.21.2",
3
+ "version": "8.22.0",
4
4
  "private": false,
5
5
  "description": "Workit Cursor plugin — shared MCP transport, native hooks, and sixteen method skills",
6
6
  "keywords": [
@@ -46,8 +46,8 @@
46
46
  "build": "bun scripts/build.ts"
47
47
  },
48
48
  "devDependencies": {
49
- "@brainervirus/workit-core": "^8.21.2",
50
- "@brainervirus/workit-mcp": "^8.21.2"
49
+ "@brainervirus/workit-core": "^8.22.0",
50
+ "@brainervirus/workit-mcp": "^8.22.0"
51
51
  },
52
52
  "engines": {
53
53
  "node": ">=24"