@brainervirus/workit-cursor 8.11.0 → 8.12.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.
- package/.cursor-plugin/plugin.json +1 -1
- package/dist/cursor-session-start.js +34 -13
- package/dist/mcp-server.js +5 -4
- package/dist/workit-hook.js +34 -13
- package/package.json +3 -3
- package/skills/workit-fanout/references/brief.md +23 -8
- package/skills/workit-fanout/references/orchestration.md +9 -4
|
@@ -9120,8 +9120,8 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
9120
9120
|
profiles: record(nonBlank, profileSchema).optional()
|
|
9121
9121
|
}).passthrough();
|
|
9122
9122
|
return entrySchema;
|
|
9123
|
-
}, resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd, "vcs"), runtimeWorkspaceIndexSchema, matchRuntimeWorkspace = (cwd) => {
|
|
9124
|
-
const file = path3.join(
|
|
9123
|
+
}, resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd, "vcs"), runtimeWorkspaceIndexSchema, matchRuntimeWorkspace = (cwd, dir = configDir()) => {
|
|
9124
|
+
const file = path3.join(dir, "workspaces.json");
|
|
9125
9125
|
let raw;
|
|
9126
9126
|
try {
|
|
9127
9127
|
raw = readFileSync2(file, "utf8");
|
|
@@ -9150,10 +9150,27 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
9150
9150
|
const matches = matchingEntries(cwd, entries ?? []);
|
|
9151
9151
|
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
9152
9152
|
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
9153
|
-
return selected ? { file, selected } : null;
|
|
9153
|
+
return selected ? { file, selected, matches } : null;
|
|
9154
9154
|
}, resolveRuntimeReleaseTracks = (cwd) => {
|
|
9155
9155
|
const matched = matchRuntimeWorkspace(cwd);
|
|
9156
9156
|
return matched ? { workspace: matched.selected.name, releaseTracks: matched.selected.releaseTracks } : null;
|
|
9157
|
+
}, workspaceTrailers = (cwd, dir) => {
|
|
9158
|
+
let matched;
|
|
9159
|
+
try {
|
|
9160
|
+
matched = matchRuntimeWorkspace(cwd, dir);
|
|
9161
|
+
} catch {
|
|
9162
|
+
return { enabled: true, workspace: null, from: null };
|
|
9163
|
+
}
|
|
9164
|
+
if (!matched)
|
|
9165
|
+
return { enabled: true, workspace: null, from: null };
|
|
9166
|
+
const { selected, matches } = matched;
|
|
9167
|
+
const enclosing = matches.filter((entry) => entry !== selected).toSorted((a, b) => globSpecificity(b.glob) - globSpecificity(a.glob));
|
|
9168
|
+
const source = [selected, ...enclosing].find((entry) => typeof entry.trailers === "boolean");
|
|
9169
|
+
return {
|
|
9170
|
+
enabled: source?.trailers !== false,
|
|
9171
|
+
workspace: selected.name,
|
|
9172
|
+
from: source?.name ?? null
|
|
9173
|
+
};
|
|
9157
9174
|
}, resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
|
|
9158
9175
|
const matched = matchRuntimeWorkspace(cwd);
|
|
9159
9176
|
if (!matched)
|
|
@@ -9264,6 +9281,7 @@ var init_workspaces = __esm(() => {
|
|
|
9264
9281
|
autoApprove: union([boolean2(), array(nonBlank)]).optional(),
|
|
9265
9282
|
defaultEndpoint: unknown().optional(),
|
|
9266
9283
|
verification: _enum(["self", "independent"]).optional(),
|
|
9284
|
+
trailers: boolean2().optional(),
|
|
9267
9285
|
autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
9268
9286
|
kind,
|
|
9269
9287
|
union([boolean2(), literal("verified")]).optional()
|
|
@@ -14783,7 +14801,7 @@ function loadCheckConfig(cwd) {
|
|
|
14783
14801
|
gates[gate] = names;
|
|
14784
14802
|
}
|
|
14785
14803
|
}
|
|
14786
|
-
return { source: CHECKS_FILE, root, checks, gates, error: null };
|
|
14804
|
+
return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
|
|
14787
14805
|
}
|
|
14788
14806
|
function matchesNamedCheck(config, name, argv, cwd) {
|
|
14789
14807
|
if (config.error || name === null || cwd !== ".")
|
|
@@ -15550,9 +15568,9 @@ Autonomy contract:
|
|
|
15550
15568
|
ship), go to the effective endpoint in \`workit grant show\`: \`pr\` opens
|
|
15551
15569
|
the PR; \`green\` babysits it without asking (workit-ship) to merge-ready,
|
|
15552
15570
|
never merging; \`merged\` also lands it with \`workit pr merge\`.
|
|
15553
|
-
Merge and release need a workspace grant
|
|
15554
|
-
|
|
15555
|
-
|
|
15571
|
+
Merge and release need a workspace grant only the user raises from their
|
|
15572
|
+
own terminal (a blocked verb names how); never edit workspaces.json or route
|
|
15573
|
+
around a grant_required.
|
|
15556
15574
|
- Ask only for a product or preference choice, or for authority you lack, with
|
|
15557
15575
|
your recommended answer. Facts are yours: read, run or prototype.
|
|
15558
15576
|
- Label claims measured (run and seen this session), inferred, or guess.
|
|
@@ -15561,17 +15579,19 @@ Autonomy contract:
|
|
|
15561
15579
|
- Author is not verifier: your own verdict is \`--self\`, shown as
|
|
15562
15580
|
self-reviewed, never verified. High risk, \`verification: independent\` and
|
|
15563
15581
|
merge need a verifier with its own host-derived session (a subagent's
|
|
15564
|
-
\`<lead>:<child
|
|
15582
|
+
\`<lead>:<child>\`); never hand-mint one (\`<lead>-v1\`).
|
|
15565
15583
|
- A local-commit endpoint does not imply PR readiness, and a local commit alone
|
|
15566
15584
|
is not evidence of a requested remote push. Before reporting delivery,
|
|
15567
15585
|
reconcile every requested item and observe it (\`workit verify-delivery\`).
|
|
15568
15586
|
|
|
15569
15587
|
CLI first: if a step has one right answer, use the \`workit\` verb instead of
|
|
15570
15588
|
hand-running git, gh or glab (\`workit git|pr|ci|check\`; \`workit help\` lists
|
|
15571
|
-
the rest;
|
|
15589
|
+
the rest; lacking \`workit\`, \`npx -y @brainervirus/workit-cli\`).
|
|
15590
|
+
Add Co-Authored-By via \`workit git commit --trailer "K: v" -- <paths>\`, never
|
|
15591
|
+
an amend.
|
|
15572
15592
|
The task families (task, policy, evidence, finding, decision, worker, state)
|
|
15573
15593
|
are optional continuity for tracked work; each branch has one implicit task,
|
|
15574
|
-
|
|
15594
|
+
and a solo edit needs no task. A decision
|
|
15575
15595
|
records a user choice; it never authorizes an effect. Judge work once with
|
|
15576
15596
|
\`workit policy assess --judge risk= behavior= product-choice= plan=\`.
|
|
15577
15597
|
Across repositories, bind each item to its checkout, branch and endpoint,
|
|
@@ -19362,16 +19382,16 @@ var usable2 = (value) => value === "native" || value === "partial", NONE5, resen
|
|
|
19362
19382
|
const prefix = descriptor.subagents.agentPrefix;
|
|
19363
19383
|
const name = agentType.startsWith(prefix) ? agentType.slice(prefix.length) : "";
|
|
19364
19384
|
return Object.hasOwn(ROLES, name) ? ROLES[name] : null;
|
|
19365
|
-
}, subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128), CLAUDE_WORKTREE,
|
|
19385
|
+
}, subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128), CLAUDE_WORKTREE, isolatedGit = (cwd) => `Run git as plain, separate commands inside your worktree (\`git switch -c <branch> <base>\`, ${workspaceTrailers(cwd).enabled ? '`git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a prepare-commit-msg hook that adds the trailer' : "`git commit` (this workspace sets trailers: false: add no Workit-Session trailer), `git push`"}; add Co-Authored-By with \`git commit --trailer\` in the same commit, never by amending), never \`workit git …\`: Claude Code's worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (\`workit check\`, \`workit ledger\`, \`workit pr\`).`, subagentStartText = (input, descriptor, event) => {
|
|
19366
19386
|
const session = input.session.id ?? null;
|
|
19367
19387
|
const role = workitRole(descriptor, event.agentType);
|
|
19368
19388
|
const who = `${descriptor.label} subagent ${event.agentId} (${event.agentType})`;
|
|
19369
19389
|
const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" || CLAUDE_WORKTREE.test(input.cwd));
|
|
19370
19390
|
const guide = role === "implementer" ? branchGuidance(input.cwd) : null;
|
|
19371
19391
|
if (role === "implementer" && isolated)
|
|
19372
|
-
return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${
|
|
19392
|
+
return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${isolatedGit(input.cwd)} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
|
|
19373
19393
|
if (isolated)
|
|
19374
|
-
return `${
|
|
19394
|
+
return `${isolatedGit(input.cwd)}
|
|
19375
19395
|
${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
|
|
19376
19396
|
if (role === "implementer")
|
|
19377
19397
|
return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree (the lead makes one with \`workit fanout worktree create <slice>\`), never in the lead's checkout, within its brief's scope. Before the first commit, switch to a policy-compliant branch with \`workit git branch <branch> --base <base>\` (or \`--kind <kind> --slug <slug>\`, which picks the base); branch policy hooks still deny protected or non-compliant branches, raw git included.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
|
|
@@ -19413,6 +19433,7 @@ ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
|
|
|
19413
19433
|
var init_handle = __esm(() => {
|
|
19414
19434
|
init_context();
|
|
19415
19435
|
init_branch();
|
|
19436
|
+
init_workspaces();
|
|
19416
19437
|
init_host_session();
|
|
19417
19438
|
init_policy();
|
|
19418
19439
|
init_raw_git();
|
package/dist/mcp-server.js
CHANGED
|
@@ -21230,7 +21230,7 @@ function loadCheckConfig(cwd) {
|
|
|
21230
21230
|
gates[gate] = names;
|
|
21231
21231
|
}
|
|
21232
21232
|
}
|
|
21233
|
-
return { source: CHECKS_FILE, root, checks, gates, error: null };
|
|
21233
|
+
return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
|
|
21234
21234
|
}
|
|
21235
21235
|
var sameArgv = (left, right) => left.length === right.length && left.every((item, index) => item === right[index]);
|
|
21236
21236
|
function matchesNamedCheck(config, name, argv, cwd) {
|
|
@@ -21818,6 +21818,7 @@ var workspaceConfigSchema = object2({
|
|
|
21818
21818
|
autoApprove: union([boolean2(), array(nonBlank)]).optional(),
|
|
21819
21819
|
defaultEndpoint: unknown().optional(),
|
|
21820
21820
|
verification: _enum(["self", "independent"]).optional(),
|
|
21821
|
+
trailers: boolean2().optional(),
|
|
21821
21822
|
autonomy: object2(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
21822
21823
|
kind,
|
|
21823
21824
|
union([boolean2(), literal("verified")]).optional()
|
|
@@ -22099,8 +22100,8 @@ var resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd,
|
|
|
22099
22100
|
var runtimeWorkspaceIndexSchema = object2({
|
|
22100
22101
|
workspaces: array(object2({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
22101
22102
|
}).passthrough();
|
|
22102
|
-
var matchRuntimeWorkspace = (cwd) => {
|
|
22103
|
-
const file = path10.join(
|
|
22103
|
+
var matchRuntimeWorkspace = (cwd, dir = configDir()) => {
|
|
22104
|
+
const file = path10.join(dir, "workspaces.json");
|
|
22104
22105
|
let raw;
|
|
22105
22106
|
try {
|
|
22106
22107
|
raw = readFileSync3(file, "utf8");
|
|
@@ -22129,7 +22130,7 @@ var matchRuntimeWorkspace = (cwd) => {
|
|
|
22129
22130
|
const matches = matchingEntries(cwd, entries ?? []);
|
|
22130
22131
|
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
22131
22132
|
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
22132
|
-
return selected ? { file, selected } : null;
|
|
22133
|
+
return selected ? { file, selected, matches } : null;
|
|
22133
22134
|
};
|
|
22134
22135
|
var resolveRuntimeReleaseTracks = (cwd) => {
|
|
22135
22136
|
const matched = matchRuntimeWorkspace(cwd);
|
package/dist/workit-hook.js
CHANGED
|
@@ -8921,6 +8921,7 @@ var workspaceConfigSchema = object({
|
|
|
8921
8921
|
autoApprove: union([boolean2(), array(nonBlank)]).optional(),
|
|
8922
8922
|
defaultEndpoint: unknown().optional(),
|
|
8923
8923
|
verification: _enum(["self", "independent"]).optional(),
|
|
8924
|
+
trailers: boolean2().optional(),
|
|
8924
8925
|
autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
8925
8926
|
kind,
|
|
8926
8927
|
union([boolean2(), literal("verified")]).optional()
|
|
@@ -9202,8 +9203,8 @@ var resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd,
|
|
|
9202
9203
|
var runtimeWorkspaceIndexSchema = object({
|
|
9203
9204
|
workspaces: array(object({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
9204
9205
|
}).passthrough();
|
|
9205
|
-
var matchRuntimeWorkspace = (cwd) => {
|
|
9206
|
-
const file = path3.join(
|
|
9206
|
+
var matchRuntimeWorkspace = (cwd, dir = configDir()) => {
|
|
9207
|
+
const file = path3.join(dir, "workspaces.json");
|
|
9207
9208
|
let raw;
|
|
9208
9209
|
try {
|
|
9209
9210
|
raw = readFileSync2(file, "utf8");
|
|
@@ -9232,12 +9233,30 @@ var matchRuntimeWorkspace = (cwd) => {
|
|
|
9232
9233
|
const matches = matchingEntries(cwd, entries ?? []);
|
|
9233
9234
|
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
9234
9235
|
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
9235
|
-
return selected ? { file, selected } : null;
|
|
9236
|
+
return selected ? { file, selected, matches } : null;
|
|
9236
9237
|
};
|
|
9237
9238
|
var resolveRuntimeReleaseTracks = (cwd) => {
|
|
9238
9239
|
const matched = matchRuntimeWorkspace(cwd);
|
|
9239
9240
|
return matched ? { workspace: matched.selected.name, releaseTracks: matched.selected.releaseTracks } : null;
|
|
9240
9241
|
};
|
|
9242
|
+
var workspaceTrailers = (cwd, dir) => {
|
|
9243
|
+
let matched;
|
|
9244
|
+
try {
|
|
9245
|
+
matched = matchRuntimeWorkspace(cwd, dir);
|
|
9246
|
+
} catch {
|
|
9247
|
+
return { enabled: true, workspace: null, from: null };
|
|
9248
|
+
}
|
|
9249
|
+
if (!matched)
|
|
9250
|
+
return { enabled: true, workspace: null, from: null };
|
|
9251
|
+
const { selected, matches } = matched;
|
|
9252
|
+
const enclosing = matches.filter((entry) => entry !== selected).toSorted((a, b) => globSpecificity(b.glob) - globSpecificity(a.glob));
|
|
9253
|
+
const source = [selected, ...enclosing].find((entry) => typeof entry.trailers === "boolean");
|
|
9254
|
+
return {
|
|
9255
|
+
enabled: source?.trailers !== false,
|
|
9256
|
+
workspace: selected.name,
|
|
9257
|
+
from: source?.name ?? null
|
|
9258
|
+
};
|
|
9259
|
+
};
|
|
9241
9260
|
var resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
|
|
9242
9261
|
const matched = matchRuntimeWorkspace(cwd);
|
|
9243
9262
|
if (!matched)
|
|
@@ -14838,7 +14857,7 @@ function loadCheckConfig(cwd) {
|
|
|
14838
14857
|
gates[gate] = names;
|
|
14839
14858
|
}
|
|
14840
14859
|
}
|
|
14841
|
-
return { source: CHECKS_FILE, root, checks, gates, error: null };
|
|
14860
|
+
return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
|
|
14842
14861
|
}
|
|
14843
14862
|
var sameArgv = (left, right) => left.length === right.length && left.every((item, index) => item === right[index]);
|
|
14844
14863
|
function matchesNamedCheck(config, name, argv, cwd) {
|
|
@@ -15605,9 +15624,9 @@ Autonomy contract:
|
|
|
15605
15624
|
ship), go to the effective endpoint in \`workit grant show\`: \`pr\` opens
|
|
15606
15625
|
the PR; \`green\` babysits it without asking (workit-ship) to merge-ready,
|
|
15607
15626
|
never merging; \`merged\` also lands it with \`workit pr merge\`.
|
|
15608
|
-
Merge and release need a workspace grant
|
|
15609
|
-
|
|
15610
|
-
|
|
15627
|
+
Merge and release need a workspace grant only the user raises from their
|
|
15628
|
+
own terminal (a blocked verb names how); never edit workspaces.json or route
|
|
15629
|
+
around a grant_required.
|
|
15611
15630
|
- Ask only for a product or preference choice, or for authority you lack, with
|
|
15612
15631
|
your recommended answer. Facts are yours: read, run or prototype.
|
|
15613
15632
|
- Label claims measured (run and seen this session), inferred, or guess.
|
|
@@ -15616,17 +15635,19 @@ Autonomy contract:
|
|
|
15616
15635
|
- Author is not verifier: your own verdict is \`--self\`, shown as
|
|
15617
15636
|
self-reviewed, never verified. High risk, \`verification: independent\` and
|
|
15618
15637
|
merge need a verifier with its own host-derived session (a subagent's
|
|
15619
|
-
\`<lead>:<child
|
|
15638
|
+
\`<lead>:<child>\`); never hand-mint one (\`<lead>-v1\`).
|
|
15620
15639
|
- A local-commit endpoint does not imply PR readiness, and a local commit alone
|
|
15621
15640
|
is not evidence of a requested remote push. Before reporting delivery,
|
|
15622
15641
|
reconcile every requested item and observe it (\`workit verify-delivery\`).
|
|
15623
15642
|
|
|
15624
15643
|
CLI first: if a step has one right answer, use the \`workit\` verb instead of
|
|
15625
15644
|
hand-running git, gh or glab (\`workit git|pr|ci|check\`; \`workit help\` lists
|
|
15626
|
-
the rest;
|
|
15645
|
+
the rest; lacking \`workit\`, \`npx -y @brainervirus/workit-cli\`).
|
|
15646
|
+
Add Co-Authored-By via \`workit git commit --trailer "K: v" -- <paths>\`, never
|
|
15647
|
+
an amend.
|
|
15627
15648
|
The task families (task, policy, evidence, finding, decision, worker, state)
|
|
15628
15649
|
are optional continuity for tracked work; each branch has one implicit task,
|
|
15629
|
-
|
|
15650
|
+
and a solo edit needs no task. A decision
|
|
15630
15651
|
records a user choice; it never authorizes an effect. Judge work once with
|
|
15631
15652
|
\`workit policy assess --judge risk= behavior= product-choice= plan=\`.
|
|
15632
15653
|
Across repositories, bind each item to its checkout, branch and endpoint,
|
|
@@ -19402,7 +19423,7 @@ var workitRole = (descriptor, agentType) => {
|
|
|
19402
19423
|
};
|
|
19403
19424
|
var subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128);
|
|
19404
19425
|
var CLAUDE_WORKTREE = /[\\/]\.claude[\\/]worktrees[\\/]/;
|
|
19405
|
-
var
|
|
19426
|
+
var isolatedGit = (cwd) => `Run git as plain, separate commands inside your worktree (\`git switch -c <branch> <base>\`, ${workspaceTrailers(cwd).enabled ? '`git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a prepare-commit-msg hook that adds the trailer' : "`git commit` (this workspace sets trailers: false: add no Workit-Session trailer), `git push`"}; add Co-Authored-By with \`git commit --trailer\` in the same commit, never by amending), never \`workit git …\`: Claude Code's worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (\`workit check\`, \`workit ledger\`, \`workit pr\`).`;
|
|
19406
19427
|
var subagentStartText = (input, descriptor, event) => {
|
|
19407
19428
|
const session = input.session.id ?? null;
|
|
19408
19429
|
const role = workitRole(descriptor, event.agentType);
|
|
@@ -19410,9 +19431,9 @@ var subagentStartText = (input, descriptor, event) => {
|
|
|
19410
19431
|
const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" || CLAUDE_WORKTREE.test(input.cwd));
|
|
19411
19432
|
const guide = role === "implementer" ? branchGuidance(input.cwd) : null;
|
|
19412
19433
|
if (role === "implementer" && isolated)
|
|
19413
|
-
return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${
|
|
19434
|
+
return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${isolatedGit(input.cwd)} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
|
|
19414
19435
|
if (isolated)
|
|
19415
|
-
return `${
|
|
19436
|
+
return `${isolatedGit(input.cwd)}
|
|
19416
19437
|
${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
|
|
19417
19438
|
if (role === "implementer")
|
|
19418
19439
|
return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree (the lead makes one with \`workit fanout worktree create <slice>\`), never in the lead's checkout, within its brief's scope. Before the first commit, switch to a policy-compliant branch with \`workit git branch <branch> --base <base>\` (or \`--kind <kind> --slug <slug>\`, which picks the base); branch policy hooks still deny protected or non-compliant branches, raw git included.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cursor",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.12.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
|
"dependencies": {
|
|
49
|
-
"@brainervirus/workit-core": "^8.
|
|
50
|
-
"@brainervirus/workit-mcp": "^8.
|
|
49
|
+
"@brainervirus/workit-core": "^8.12.0",
|
|
50
|
+
"@brainervirus/workit-mcp": "^8.12.0"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=24"
|
|
@@ -25,7 +25,7 @@ REPORT: branch, head SHA, files changed, each VERIFY command with its exit code,
|
|
|
25
25
|
each ACCEPTANCE line met / not met, rulings you made (`workit ledger ruling`),
|
|
26
26
|
anything out of scope as a follow-up, not a diff.
|
|
27
27
|
STANDING: <the standing orders, verbatim: `workit ledger standing add` records each one>
|
|
28
|
-
|
|
28
|
+
<identity line, per the lead's host: see "Identity and git rules per host" below>
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
## Worked example
|
|
@@ -97,17 +97,32 @@ is the slice's STUCK threshold in `workit fanout status`. `"fanIn":
|
|
|
97
97
|
}
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
+
## Identity and git rules per host
|
|
101
|
+
|
|
102
|
+
`workit fanout brief` renders the identity line and RULES 1 and 3 for the
|
|
103
|
+
lead's host (`WORKIT_HOST`, or the host's own session variable):
|
|
104
|
+
|
|
105
|
+
| Lead's host | Identity line | RULES 1 and 3 |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| Claude Code | `Session: your env already has WORKIT_SESSION_ID (the lead's id)`; no `export`, no hand-minted id (SubagentStart issues `<lead>:<agent id>` only to verifiers and reviewers, never to an implementer, so the worker's commits carry the lead's id) | plain git: `git fetch origin && git switch -c <branch> origin/<base>` and `git commit -m <msg> --trailer "Workit-Session: <the env WORKIT_SESSION_ID>" --trailer "<host attribution>" -- <paths in SCOPE>`, because worktree isolation refuses every `workit git` form |
|
|
108
|
+
| OpenCode, Pi, Codex | `Session: your host already sets WORKIT_SESSION_ID in your shell`; export nothing (the host derives the id and an export cannot replace it) | `workit git branch <branch> --base <base>`, `workit git commit -m <msg> -- <paths in SCOPE>` |
|
|
109
|
+
| Cursor, CI, a plain terminal | `export WORKIT_SESSION_ID=<lead>-w-<slice>` (`+try<n>` for a race attempt): declared, not checked | the same `workit git` forms |
|
|
110
|
+
|
|
111
|
+
`MODE: resume` is `git switch <branch>` on every host (the branch exists; the
|
|
112
|
+
lead removed the dead worker's worktree after its exit, so the switch
|
|
113
|
+
succeeds), then continue from its head. A race attempt (`--attempt <n>`)
|
|
114
|
+
follows its host's row with the branch `<branch>-try<n>`.
|
|
115
|
+
|
|
100
116
|
## Worker rules (`workit fanout brief` appends them as RULES)
|
|
101
117
|
|
|
102
|
-
1. First command
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
worker's worktree after its exit, so the switch succeeds), then continue
|
|
106
|
-
from its head.
|
|
118
|
+
1. First command: create the branch (`MODE: new`; the worktree may start on a
|
|
119
|
+
name that breaks branch policy) or `git switch` to it (`MODE: resume`),
|
|
120
|
+
as the table above says for your host.
|
|
107
121
|
2. Decide ambiguities yourself and record them:
|
|
108
122
|
`workit ledger ruling "<what>" --why "<why>" --cost-if-wrong "<cost>"`.
|
|
109
123
|
Stop only for an irreversible action, a security-sensitive one, or a side
|
|
110
124
|
effect outside the worktree.
|
|
111
|
-
3. Commit
|
|
112
|
-
the brief says
|
|
125
|
+
3. Commit as the table says (`workit git commit -m "<msg>" -- <paths in SCOPE>`,
|
|
126
|
+
or plain git with the trailers on Claude Code); push only if the brief says
|
|
127
|
+
so.
|
|
113
128
|
4. Never record a verdict on your own work.
|
|
@@ -73,8 +73,8 @@ Which session id a verdict carries, per host:
|
|
|
73
73
|
- Claude Code: subagents inherit your `WORKIT_SESSION_ID`, so the
|
|
74
74
|
SubagentStart hook names each `verifier` and `reviewer` its own session
|
|
75
75
|
(`<lead>:<agent id>`), passed exactly as `--session`: the hook records the
|
|
76
|
-
ids it issues, and only those are accepted. An `implementer`
|
|
77
|
-
|
|
76
|
+
ids it issues, and only those are accepted. An `implementer` is issued
|
|
77
|
+
none: it keeps your id in its env for its workit commands and commits.
|
|
78
78
|
- Codex: the `workit-verifier` and `workit-reviewer` agents get the same
|
|
79
79
|
issued `--session` from SubagentStart; any other verifier passes
|
|
80
80
|
`--as verifier`.
|
|
@@ -84,8 +84,13 @@ Which session id a verdict carries, per host:
|
|
|
84
84
|
- Cursor (no session id in the shell): the brief sets the verifier's
|
|
85
85
|
`WORKIT_SESSION_ID=<lead>:verifier-<random hex>`, a fresh suffix per
|
|
86
86
|
verifier. Cursor cannot check it: it is declared, not derived.
|
|
87
|
-
- A worker's commits
|
|
88
|
-
|
|
87
|
+
- A worker's commits: on Claude Code the lead's `WORKIT_SESSION_ID` already in
|
|
88
|
+
its env (SubagentStart issues no implementer id; plain git, no export, so the
|
|
89
|
+
lead authored those commits: a verifier or reviewer records the verdict, not
|
|
90
|
+
the lead); on OpenCode, Pi and Codex the id the host already
|
|
91
|
+
puts in its shell; on Cursor, CI and a plain terminal the brief's
|
|
92
|
+
`export WORKIT_SESSION_ID=<lead>-w-<slice>` (see `brief.md`, "Identity and
|
|
93
|
+
git rules per host"). A verdict under an id you made up (`<lead>-v1`,
|
|
89
94
|
`<lead>:v1`) is refused as `forged_session` on Claude Code, Codex,
|
|
90
95
|
OpenCode and Pi.
|
|
91
96
|
|