@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.
- package/.cursor-plugin/plugin.json +1 -1
- package/dist/cursor-session-start.js +46 -5
- package/dist/workit-hook.js +48 -3
- package/package.json +3 -3
- package/skills/workit-implement/SKILL.md +5 -3
- package/skills/workit-verify-app/SKILL.md +6 -2
- package/skills/workit-verify-app/references/template.md +2 -0
|
@@ -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
|
|
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("'", "'\\''")}'`,
|
|
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) =>
|
|
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)],
|
|
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();
|
package/dist/workit-hook.js
CHANGED
|
@@ -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
|
|
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) =>
|
|
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.
|
|
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.
|
|
50
|
-
"@brainervirus/workit-mcp": "^8.19.
|
|
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 (
|
|
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`
|
|
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>`).
|