@brainervirus/workit-cursor 8.19.0 → 8.19.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.
@@ -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.19.0",
5
+ "version": "8.19.2",
6
6
  "author": {
7
7
  "name": "Cristhofer Pincetti"
8
8
  },
@@ -21296,6 +21296,9 @@ import { realpathSync as realpathSync5 } from "node:fs";
21296
21296
  import os10 from "node:os";
21297
21297
  import path26 from "node:path";
21298
21298
  function writeGate(cwd, paths, owner, deps) {
21299
+ const forged = paths?.length ? issuedTarget(cwd, paths) : null;
21300
+ if (forged)
21301
+ return issuedDeny(forged);
21299
21302
  if (!owner)
21300
21303
  return beforeWriteGate(cwd, paths);
21301
21304
  const targets = liveTargets(cwd, paths);
@@ -21308,6 +21311,11 @@ function writeGate(cwd, paths, owner, deps) {
21308
21311
  return decision;
21309
21312
  }
21310
21313
  function shellGate(cwd, command, owner, dialect = "posix", deps) {
21314
+ try {
21315
+ const forged = issuedTarget(cwd, segmentTargets(cwd, command, dialect)) ?? (unquotedWindowsIssued(command) ? "the issued registry" : null);
21316
+ if (forged)
21317
+ return issuedDeny(forged);
21318
+ } catch {}
21311
21319
  const writes = shellWrites(command);
21312
21320
  let targets = [];
21313
21321
  if (owner) {
@@ -21354,7 +21362,7 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21354
21362
  let rest = "";
21355
21363
  for (let dir = path26.resolve(file);; dir = path26.dirname(dir)) {
21356
21364
  try {
21357
- return path26.join(realpathSync5(dir), rest);
21365
+ return path26.join(realpathSync5.native(dir), rest);
21358
21366
  } catch {
21359
21367
  if (path26.dirname(dir) === dir)
21360
21368
  return path26.resolve(file);
@@ -21535,16 +21543,23 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21535
21543
  return [path26.resolve(cwd, invocation.dir ?? ".")];
21536
21544
  });
21537
21545
  }, CD2, PUSHD2, POPD2, cdInto = (dir, words) => {
21538
- const target = words.slice(1).find((word) => !word.startsWith("-") || word === "-");
21546
+ const named = words.slice(1).find((word) => !word.startsWith("-") || word === "-");
21547
+ const target = named === undefined ? undefined : homeExpanded(named);
21539
21548
  if (dir === undefined || target === "-" || target && /^~|[$`*?]/.test(target))
21540
21549
  return;
21541
21550
  return target === undefined ? os10.homedir() : path26.resolve(dir, target);
21542
- }, quoteWord2 = (word) => /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`, segmentTargets = (cwd, command, dialect, depth = 0) => {
21551
+ }, quoteWord2 = (word) => /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`, homeExpanded = (file) => {
21552
+ const match = /^(?:~|\$HOME|\$\{HOME\})(?=\/|$)/.exec(file);
21553
+ return match ? (process.env.HOME || os10.homedir()) + file.slice(match[0].length) : file;
21554
+ }, segmentTargets = (cwd, command, dialect, depth = 0) => {
21543
21555
  const targets = [];
21544
21556
  let dir = cwd;
21545
21557
  let stack = [];
21546
21558
  const groups = [];
21547
- const at = (file) => path26.isAbsolute(file) ? file : dir === undefined ? null : path26.resolve(dir, file);
21559
+ const at = (file) => {
21560
+ const home = homeExpanded(file);
21561
+ return path26.isAbsolute(home) ? home : dir === undefined ? null : path26.resolve(dir, home);
21562
+ };
21548
21563
  for (const segment of segmentsOf(command, dialect)) {
21549
21564
  if (segment.group === "open") {
21550
21565
  groups.push({ dir, stack: [...stack] });
@@ -21633,7 +21648,32 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21633
21648
  }, claimAll = (owner, targets, deps) => {
21634
21649
  for (const target of guarded(targets))
21635
21650
  claimLiveSession(target, owner, deps);
21636
- }, liveTargets = (cwd, paths) => paths?.length ? paths.map((file) => path26.resolve(cwd, file)) : [path26.join(cwd, DIR_TARGET)], noteOverride = (cwd, owner, command) => {
21651
+ }, liveTargets = (cwd, paths) => paths?.length ? paths.map((file) => path26.resolve(cwd, file)) : [path26.join(cwd, DIR_TARGET)], issuedTarget = (cwd, targets) => {
21652
+ const state = resolveStateDir();
21653
+ const found = targets.find((target) => underIssued(state, cwd, homeExpanded(target), process.platform, canonical2));
21654
+ return found ?? null;
21655
+ }, underIssued = (state, cwd, target, platform = process.platform, real = (file) => file) => {
21656
+ const win = platform === "win32";
21657
+ const p = win ? path26.win32 : path26.posix;
21658
+ const fold = (value) => win || platform === "darwin" ? value.toLowerCase() : value;
21659
+ const named = win ? target.replace(/^\/([a-zA-Z])(?=\/|$)/, "$1:") : target;
21660
+ const relative = p.relative(fold(real(p.resolve(state))), fold(real(p.resolve(cwd, named))));
21661
+ if (relative.startsWith("..") || p.isAbsolute(relative))
21662
+ return false;
21663
+ return relative.split(p.sep)[0].startsWith("issued");
21664
+ }, unquotedWindowsIssued = (command) => {
21665
+ if (process.platform !== "win32" || !command.includes("\\"))
21666
+ return false;
21667
+ const flat = (value) => value.replaceAll("\\", "/").toLowerCase();
21668
+ return flat(command).includes(`${flat(resolveStateDir())}/issued`) && shellWrites(command).writes;
21669
+ }, issuedDeny = (file) => {
21670
+ const unblock = "Issued ids and tokens are written only by Workit's SubagentStart hook. Run the verifier or reviewer agent so the host issues its own session; never edit the issued registries by hand.";
21671
+ return {
21672
+ kind: "deny",
21673
+ reason: `workit issued-registry guard: ${file} is under Workit's issued-session state. ${unblock}`,
21674
+ unblock
21675
+ };
21676
+ }, noteOverride = (cwd, owner, command) => {
21637
21677
  try {
21638
21678
  if (!inWorkitWorkspace(cwd))
21639
21679
  return;
@@ -21650,6 +21690,7 @@ var init_write_gate = __esm(() => {
21650
21690
  init_derive();
21651
21691
  init_task_evaluation();
21652
21692
  init_live_session();
21693
+ init_logger();
21653
21694
  init_workspaces();
21654
21695
  init_ledger();
21655
21696
  init_raw_git();
@@ -21508,7 +21508,7 @@ var canonical2 = (file) => {
21508
21508
  let rest = "";
21509
21509
  for (let dir = path26.resolve(file);; dir = path26.dirname(dir)) {
21510
21510
  try {
21511
- return path26.join(realpathSync5(dir), rest);
21511
+ return path26.join(realpathSync5.native(dir), rest);
21512
21512
  } catch {
21513
21513
  if (path26.dirname(dir) === dir)
21514
21514
  return path26.resolve(file);
@@ -21728,18 +21728,26 @@ var CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
21728
21728
  var PUSHD2 = new Set(["pushd", "push-location"]);
21729
21729
  var POPD2 = new Set(["popd", "pop-location"]);
21730
21730
  var cdInto = (dir, words) => {
21731
- const target = words.slice(1).find((word) => !word.startsWith("-") || word === "-");
21731
+ const named = words.slice(1).find((word) => !word.startsWith("-") || word === "-");
21732
+ const target = named === undefined ? undefined : homeExpanded(named);
21732
21733
  if (dir === undefined || target === "-" || target && /^~|[$`*?]/.test(target))
21733
21734
  return;
21734
21735
  return target === undefined ? os10.homedir() : path26.resolve(dir, target);
21735
21736
  };
21736
21737
  var quoteWord2 = (word) => /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`;
21738
+ var homeExpanded = (file) => {
21739
+ const match = /^(?:~|\$HOME|\$\{HOME\})(?=\/|$)/.exec(file);
21740
+ return match ? (process.env.HOME || os10.homedir()) + file.slice(match[0].length) : file;
21741
+ };
21737
21742
  var segmentTargets = (cwd, command, dialect, depth = 0) => {
21738
21743
  const targets = [];
21739
21744
  let dir = cwd;
21740
21745
  let stack = [];
21741
21746
  const groups = [];
21742
- const at = (file) => path26.isAbsolute(file) ? file : dir === undefined ? null : path26.resolve(dir, file);
21747
+ const at = (file) => {
21748
+ const home = homeExpanded(file);
21749
+ return path26.isAbsolute(home) ? home : dir === undefined ? null : path26.resolve(dir, home);
21750
+ };
21743
21751
  for (const segment of segmentsOf(command, dialect)) {
21744
21752
  if (segment.group === "open") {
21745
21753
  groups.push({ dir, stack: [...stack] });
@@ -21844,7 +21852,39 @@ var claimAll = (owner, targets, deps) => {
21844
21852
  claimLiveSession(target, owner, deps);
21845
21853
  };
21846
21854
  var liveTargets = (cwd, paths) => paths?.length ? paths.map((file) => path26.resolve(cwd, file)) : [path26.join(cwd, DIR_TARGET)];
21855
+ var issuedTarget = (cwd, targets) => {
21856
+ const state = resolveStateDir();
21857
+ const found = targets.find((target) => underIssued(state, cwd, homeExpanded(target), process.platform, canonical2));
21858
+ return found ?? null;
21859
+ };
21860
+ var underIssued = (state, cwd, target, platform = process.platform, real = (file) => file) => {
21861
+ const win = platform === "win32";
21862
+ const p = win ? path26.win32 : path26.posix;
21863
+ const fold = (value) => win || platform === "darwin" ? value.toLowerCase() : value;
21864
+ const named = win ? target.replace(/^\/([a-zA-Z])(?=\/|$)/, "$1:") : target;
21865
+ const relative = p.relative(fold(real(p.resolve(state))), fold(real(p.resolve(cwd, named))));
21866
+ if (relative.startsWith("..") || p.isAbsolute(relative))
21867
+ return false;
21868
+ return relative.split(p.sep)[0].startsWith("issued");
21869
+ };
21870
+ var unquotedWindowsIssued = (command) => {
21871
+ if (process.platform !== "win32" || !command.includes("\\"))
21872
+ return false;
21873
+ const flat = (value) => value.replaceAll("\\", "/").toLowerCase();
21874
+ return flat(command).includes(`${flat(resolveStateDir())}/issued`) && shellWrites(command).writes;
21875
+ };
21876
+ var issuedDeny = (file) => {
21877
+ const unblock = "Issued ids and tokens are written only by Workit's SubagentStart hook. Run the verifier or reviewer agent so the host issues its own session; never edit the issued registries by hand.";
21878
+ return {
21879
+ kind: "deny",
21880
+ reason: `workit issued-registry guard: ${file} is under Workit's issued-session state. ${unblock}`,
21881
+ unblock
21882
+ };
21883
+ };
21847
21884
  function writeGate(cwd, paths, owner, deps) {
21885
+ const forged = paths?.length ? issuedTarget(cwd, paths) : null;
21886
+ if (forged)
21887
+ return issuedDeny(forged);
21848
21888
  if (!owner)
21849
21889
  return beforeWriteGate(cwd, paths);
21850
21890
  const targets = liveTargets(cwd, paths);
@@ -21857,6 +21897,11 @@ function writeGate(cwd, paths, owner, deps) {
21857
21897
  return decision;
21858
21898
  }
21859
21899
  function shellGate(cwd, command, owner, dialect = "posix", deps) {
21900
+ try {
21901
+ const forged = issuedTarget(cwd, segmentTargets(cwd, command, dialect)) ?? (unquotedWindowsIssued(command) ? "the issued registry" : null);
21902
+ if (forged)
21903
+ return issuedDeny(forged);
21904
+ } catch {}
21860
21905
  const writes = shellWrites(command);
21861
21906
  let targets = [];
21862
21907
  if (owner) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cursor",
3
- "version": "8.19.0",
3
+ "version": "8.19.2",
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.19.0",
50
- "@brainervirus/workit-mcp": "^8.19.0"
49
+ "@brainervirus/workit-core": "^8.19.2",
50
+ "@brainervirus/workit-mcp": "^8.19.2"
51
51
  },
52
52
  "engines": {
53
53
  "node": ">=24"
@@ -24,7 +24,10 @@ description: Build a requested change in small verified steps - follow local pat
24
24
  lease waits and names its holder (`workit lock status`).
25
25
  5. Prove the feature on its real surface with the project's `verify-<app>`
26
26
  skill; none yet? Write one (read the `workit-verify-app` skill's SKILL.md and follow it). Tests show branch behavior,
27
- not that the feature works.
27
+ not that the feature works. The report carries what you observed: a UI
28
+ change a screenshot or console/network check (chrome devtools or
29
+ agent-browser), an API a quoted real response. App not runnable? Say so
30
+ plainly, never claim success.
28
31
  6. Commit: `workit git commit -m "<type>: <what>" -- <paths>` (or `--all`).
29
32
  No endpoint named? Stop here and state the next command. Hand delivery to
30
33
  ship, which pushes and opens the PR with its body shape (read the `workit-ship` skill's SKILL.md and follow it), only
@@ -55,8 +58,7 @@ flag was never invoked)
55
58
 
56
59
  Good: "Added `--since`. measured: `workit check test` exit 0;
57
60
  `mytool log --since 2d` printed 3 entries against the fixture repo. inferred:
58
- the GitLab path behaves the same (shared parser, not run). Verification handed
59
- to the verifier agent."
61
+ the GitLab path behaves the same (not run). Handed to the verifier agent."
60
62
 
61
63
  ## Check
62
64
 
@@ -27,7 +27,10 @@ way a user would.
27
27
  - **Drive:** how to exercise it: CLI invocations, `curl` against routes, a
28
28
  browser tool for UI, with fixture data.
29
29
  - **Evidence:** what to capture (exit code, response body, screenshot path)
30
- and the command that records it.
30
+ and the command that records it. A UI is driven with chrome devtools or
31
+ agent-browser, with a screenshot or console/network observation; an API
32
+ with a real call, response quoted. The report carries the observation.
33
+ App not runnable? Say so plainly, never claim success.
31
34
  - **Cleanup:** stop processes, remove temp data.
32
35
  - **Feature map:** feature, how to drive it, expected observation.
33
36
  3. **Prove it end-to-end once:** launch, drive one feature, capture evidence,
@@ -54,7 +57,8 @@ report `clean`, `changed` (what) or `blocked` (why).
54
57
  Bad: "Verify by running the tests." (that is not the real surface)
55
58
 
56
59
  Good: "Launch `bun run dev` (ready: `listening on :5173`, 30 s). Drive:
57
- `curl -s localhost:5173/api/health` returns `{"ok":true}`. Evidence:
60
+ `curl -s localhost:5173/api/health` returned `{"ok":true}`; screenshot of
61
+ /settings at .workit-scratch/settings.png. Evidence:
58
62
  `workit check --name verify-web -- bun scripts/smoke.ts` exit 0."
59
63
 
60
64
  ## Check
@@ -30,6 +30,8 @@ description: Launch, drive and observe <app> on its real surface (<cli|web|api>)
30
30
  ## Evidence
31
31
  `workit check --name verify-<app> -- <driver command>` records exit code and log.
32
32
  Screenshots go to `<tmp dir>/verify-<app>/<feature>.png`; cite the path.
33
+ UI: also report a console or network observation. API: quote the real response.
34
+ If the app cannot be run, say so plainly instead of claiming success.
33
35
 
34
36
  ## Cleanup
35
37
  `<command>` (stop servers, remove `<tmp dir>`).