@brainervirus/workit-cursor 0.8.5 → 0.8.7
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/README.md +7 -6
- package/assets/templates/execution-contract.md +2 -0
- package/assets/templates/plan-template.md +2 -0
- package/dist/cursor-session-start.js +15 -15
- package/dist/mcp-server.js +50 -20
- package/hooks/hooks-cursor.json +1 -1
- package/mcp.json +1 -1
- package/package.json +2 -2
- package/skills/wk-handoff/SKILL.md +2 -0
- package/skills/wk-implement/SKILL.md +4 -0
- package/skills/wk-init/SKILL.md +5 -5
- package/skills/wk-issue-update/SKILL.md +1 -1
- package/skills/wk-meetings/SKILL.md +1 -1
- package/skills/wk-status/SKILL.md +2 -2
- package/vendor/superpowers/skills/subagent-driven-development/SKILL.md +9 -1
package/README.md
CHANGED
|
@@ -23,7 +23,8 @@ npx @brainervirus/workit-cli init
|
|
|
23
23
|
"command": "npx",
|
|
24
24
|
"args": [
|
|
25
25
|
"-y",
|
|
26
|
-
"--
|
|
26
|
+
"--prefer-online",
|
|
27
|
+
"--package=@brainervirus/workit-cursor@latest",
|
|
27
28
|
"workit-cursor-mcp",
|
|
28
29
|
"${workspaceFolder}"
|
|
29
30
|
]
|
|
@@ -35,7 +36,7 @@ npx @brainervirus/workit-cli init
|
|
|
35
36
|
### Requirements
|
|
36
37
|
|
|
37
38
|
- **Node.js ≥ 22** — the MCP server and session-start hook are self-contained Node bundles invoked through `npx`.
|
|
38
|
-
- **Network** — `npx -y …@
|
|
39
|
+
- **Network** — `npx -y --prefer-online …@latest` resolves and downloads the package on first run in each environment; a machine that cannot reach the npm registry cannot start the MCP server or hook (see [Runtime](#runtime)).
|
|
39
40
|
|
|
40
41
|
## What it provides
|
|
41
42
|
|
|
@@ -59,11 +60,11 @@ Cursor adapts workit through policy-only confirmation: approvals and lifecycle t
|
|
|
59
60
|
|
|
60
61
|
Cursor launches the MCP server and session-start hook through `npx`, so the shipped manifests contain no repository-relative `dist` paths:
|
|
61
62
|
|
|
62
|
-
- **MCP server** — `npx -y --package=@brainervirus/workit-cursor@
|
|
63
|
-
- **Session-start hook** — `npx -y --package=@brainervirus/workit-cursor@
|
|
63
|
+
- **MCP server** — `npx -y --prefer-online --package=@brainervirus/workit-cursor@latest workit-cursor-mcp ${workspaceFolder}`. It speaks the MCP stdio protocol; `stdout` is reserved for protocol messages and diagnostics go to `stderr`.
|
|
64
|
+
- **Session-start hook** — `npx -y --prefer-online --package=@brainervirus/workit-cursor@latest workit-cursor-session-start`. It emits valid hook output and a diagnostic on runtime failure, and remains fail-open where Cursor's hook contract requires startup continuity.
|
|
64
65
|
- `npx` startup or network failure is surfaced by Cursor as an MCP/hook startup failure; Workit never silently substitutes stale local runtime code.
|
|
65
66
|
|
|
66
|
-
The runtime runs from the
|
|
67
|
+
The runtime runs from `@latest` with the mandatory `--prefer-online` flag: Cursor reviews plugin metadata from Git, while npm serves the runtime. `--prefer-online` forces npx to check the registry so a stale cached `latest` resolution is never reused. See [Update review](#update-review).
|
|
67
68
|
|
|
68
69
|
## Security and data handling
|
|
69
70
|
|
|
@@ -96,7 +97,7 @@ The repository root carries `.cursor-plugin/marketplace.json`, indexing `package
|
|
|
96
97
|
|
|
97
98
|
- **Installing from Marketplace** — a Marketplace admin adds the repository URL through Cursor's authenticated publisher flow; end users then install the plugin from the Cursor Marketplace UI, which reads `.cursor-plugin/plugin.json` and the tracked components directly from Git.
|
|
98
99
|
- **Submission** — Marketplace submission is a separate, later authenticated action at `https://cursor.com/marketplace/publish`. It is **not** performed here and no publication or acceptance is claimed; the repository is kept validated and submission-ready.
|
|
99
|
-
- **Update review** — Git plugin metadata (manifest, rules, skills, assets) is reviewed by Cursor on Marketplace updates, while the npm runtime
|
|
100
|
+
- **Update review** — Git plugin metadata (manifest, rules, skills, assets) is reviewed by Cursor on Marketplace updates, while the npm runtime runs from `@latest` with `--prefer-online`. The selector is shared across `mcp.json`, `hooks-cursor.json`, and `run-cursor-mcp.sh`, and a stale `latest` resolution is prevented by the mandatory `--prefer-online` flag.
|
|
100
101
|
- **Troubleshooting** — `workit doctor` (or the `workflow_doctor` tool) reports installation health including runtime, token, VCS/YouTrack, and log-writability checks; it exits nonzero on failure. An MCP/hook startup failure with no network is an `npx`/registry reachability issue, not a Workit defect.
|
|
101
102
|
|
|
102
103
|
## Docs
|
|
@@ -59,6 +59,8 @@ For each top-level task absent from `completed_task_ids`:
|
|
|
59
59
|
|
|
60
60
|
Run a separate full-branch code review, then `workflow_verify`. Present the full `<SDD_DIR>/advisories.md` roll-up once, then use native `question` so the user can choose which advisory items to fix, discuss, or discard. Report exact check results and never infer success. Use `workflow_git_context` for a commit preview and load `wk-commit` through `skill` for an approved commit. If working state contains a stash reference, preview reapplication through `question`, then call `workflow_branch_setup` with `confirmed: true` after approval.
|
|
61
61
|
|
|
62
|
+
**Mandatory:** end the run by calling `workflow_plan_complete` (OpenCode/Cursor) or the CLI `workit flow complete` (CLI host) after the final task once the SDD ledger is complete (all task IDs appended) and `workflow_verify` passes — a complete ledger and green verification are the tool's gates. Never finish the run while the plan is still `active`.
|
|
63
|
+
|
|
62
64
|
## Task order
|
|
63
65
|
|
|
64
66
|
<TASK_LIST>
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
## Global Constraints
|
|
11
11
|
|
|
12
|
+
- Each task lands exactly one contiguous non-empty commit range (`base..head`): fix rounds append commits to that range and never rewrite/amend an active review range; each progress line records the task's real base..head shas.
|
|
13
|
+
- The final task ends execution with `workflow_plan_complete` (or the CLI `workit flow complete`) once the SDD ledger is complete and repository verification passes — a run never finishes while the plan is still `active`.
|
|
12
14
|
- <project-wide requirements, one line each>
|
|
13
15
|
|
|
14
16
|
---
|
|
@@ -340,7 +340,7 @@ var logger = createLogger({
|
|
|
340
340
|
});
|
|
341
341
|
var hookDir = path3.dirname(fileURLToPath(import.meta.url));
|
|
342
342
|
var pluginDir = path3.resolve(hookDir, "..");
|
|
343
|
-
var marker = path3.join(pluginDir, ".
|
|
343
|
+
var marker = path3.join(pluginDir, ".workit-root");
|
|
344
344
|
setDiagnosticLogger(logger);
|
|
345
345
|
logger.info(EVENT.initialization, { host: "cursor-hook", hook_dir: hookDir });
|
|
346
346
|
var resolveRepoRoot = () => {
|
|
@@ -409,35 +409,35 @@ var isDestination = (input) => {
|
|
|
409
409
|
};
|
|
410
410
|
var main = async () => {
|
|
411
411
|
const reminder = reminderTextFor(isDestination(await readHookInput(HOOK_READ_TIMEOUT_MS)));
|
|
412
|
-
const context = `<
|
|
412
|
+
const context = `<workit-askquestion-hard-gate>
|
|
413
413
|
HARD-GATE: Any user choice with options → call Cursor AskQuestion directly with workflow-specific copy. NEVER A/B/C in chat. Overrides Superpowers brainstorming conversational options.
|
|
414
|
-
</
|
|
414
|
+
</workit-askquestion-hard-gate>
|
|
415
415
|
|
|
416
|
-
<
|
|
416
|
+
<workit-visual-companion>
|
|
417
417
|
HARD-GATE: NEVER offer Superpowers visual companion or open a browser tab. For UI wireframes use workflow_present_ascii; for flows use workflow_present_flow. Overrides Superpowers brainstorming visual companion offer.
|
|
418
|
-
</
|
|
418
|
+
</workit-visual-companion>
|
|
419
419
|
|
|
420
|
-
<
|
|
420
|
+
<workit-no-worktrees>
|
|
421
421
|
HARD-GATE: NEVER using-git-worktrees or git worktree. In-place feature/* or bugfix/* checkout only via workflow_resolve_branch + workflow_branch_setup. Dirty tree → native AskQuestion before checkout.
|
|
422
|
-
</
|
|
422
|
+
</workit-no-worktrees>
|
|
423
423
|
|
|
424
|
-
<
|
|
424
|
+
<workit-sdd-path>
|
|
425
425
|
HARD-GATE: NEVER .superpowers/sdd. ALWAYS workflow_sdd_context with plan_path first — resolves canonical docs/<slug>/sdd/ and creates nothing (no empty ledger; progress.md appears only on the first confirmed append). workflow_sdd_task_brief, workflow_sdd_review_package, workflow_sdd_append_progress only.
|
|
426
|
-
</
|
|
426
|
+
</workit-sdd-path>
|
|
427
427
|
|
|
428
|
-
<
|
|
428
|
+
<workit-todowrite>
|
|
429
429
|
HARD-GATE: After workflow_sdd_context, call Cursor TodoWrite with returned todos (merge: false). SDD ledger is persistence — TodoWrite is the native task list UI. Keep in_progress/completed in sync each task.
|
|
430
|
-
</
|
|
430
|
+
</workit-todowrite>
|
|
431
431
|
|
|
432
|
-
<
|
|
432
|
+
<workit-superpowers-doc-contract>
|
|
433
433
|
${body}
|
|
434
|
-
</
|
|
434
|
+
</workit-superpowers-doc-contract>
|
|
435
435
|
|
|
436
|
-
<
|
|
436
|
+
<workit-reminder>
|
|
437
437
|
HARD-GATE: Bounded user choices → call Cursor AskQuestion directly (never A/B/C or 1/2/3 lists in prose).
|
|
438
438
|
|
|
439
439
|
${reminder}
|
|
440
|
-
</
|
|
440
|
+
</workit-reminder>`;
|
|
441
441
|
process.stdout.write(JSON.stringify({ additional_context: context }, null, 2) + `
|
|
442
442
|
`);
|
|
443
443
|
process.exit(0);
|
package/dist/mcp-server.js
CHANGED
|
@@ -21842,13 +21842,25 @@ function isWorkitPlugin(value) {
|
|
|
21842
21842
|
const pkgPath = s.includes("/packages/workit-opencode/") || s.includes("/packages/workit-cursor/") || s.includes("/node_modules/@brainervirus/workit-opencode/") || s.includes("/node_modules/@brainervirus/workit-cursor/");
|
|
21843
21843
|
return named(s, "workflow-toolkit") || named(s, "workflow-toolkit-opencode") || named(s, "local/workflow-toolkit") || named(s, "workit") || named(s, "local/workit") || named(s, "@brainervirus/workit-opencode") || named(s, "@brainervirus/workit-cursor") || url && pkgPath || s.startsWith("git+file://") && s.includes("workflow-toolkit");
|
|
21844
21844
|
}
|
|
21845
|
+
function cursorMcpServerEntry(_packageDir) {
|
|
21846
|
+
return {
|
|
21847
|
+
command: "npx",
|
|
21848
|
+
args: [
|
|
21849
|
+
"-y",
|
|
21850
|
+
"--prefer-online",
|
|
21851
|
+
`--package=${CURSOR_RUNTIME_PACKAGE}`,
|
|
21852
|
+
"workit-cursor-mcp",
|
|
21853
|
+
"${workspaceFolder}"
|
|
21854
|
+
]
|
|
21855
|
+
};
|
|
21856
|
+
}
|
|
21845
21857
|
function cursorHooksEntry(_packageDir) {
|
|
21846
21858
|
return {
|
|
21847
|
-
command: `npx -y --package=${CURSOR_RUNTIME_PACKAGE} workit-cursor-session-start`,
|
|
21859
|
+
command: `npx -y --prefer-online --package=${CURSOR_RUNTIME_PACKAGE} workit-cursor-session-start`,
|
|
21848
21860
|
args: []
|
|
21849
21861
|
};
|
|
21850
21862
|
}
|
|
21851
|
-
var named = (s, name) => s === name || s.startsWith(`${name}@`), CURSOR_RUNTIME_PACKAGE = "@brainervirus/workit-cursor@
|
|
21863
|
+
var named = (s, name) => s === name || s.startsWith(`${name}@`), CURSOR_RUNTIME_PACKAGE = "@brainervirus/workit-cursor@latest";
|
|
21852
21864
|
var init_registration = () => {};
|
|
21853
21865
|
|
|
21854
21866
|
// packages/workit-core/src/core/skill-manifests.ts
|
|
@@ -22189,12 +22201,9 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
22189
22201
|
return "invalid";
|
|
22190
22202
|
}
|
|
22191
22203
|
const executable = path9.basename(command).toLowerCase();
|
|
22204
|
+
const canonical = cursorMcpServerEntry("").args;
|
|
22192
22205
|
if (executable === "npx" || executable === "npx.exe" || executable === "npx.cmd") {
|
|
22193
|
-
if (args
|
|
22194
|
-
return "invalid";
|
|
22195
|
-
if (args[1] !== `--package=${CURSOR_RUNTIME_PACKAGE}`)
|
|
22196
|
-
return "invalid";
|
|
22197
|
-
if (args[2] !== "workit-cursor-mcp")
|
|
22206
|
+
if (args.length !== canonical.length || args.some((a, i) => a !== canonical[i]))
|
|
22198
22207
|
return "invalid";
|
|
22199
22208
|
return { kind: "npx" };
|
|
22200
22209
|
}
|
|
@@ -22219,6 +22228,17 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
22219
22228
|
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
22220
22229
|
return "invalid";
|
|
22221
22230
|
return typeof entry.command === "string" ? entry.command : "invalid";
|
|
22231
|
+
}, validLocalDistHook = (command, res) => {
|
|
22232
|
+
const m = /^node\s+(.+)$/.exec(command.trim());
|
|
22233
|
+
if (!m)
|
|
22234
|
+
return false;
|
|
22235
|
+
const entry = m[1].trim();
|
|
22236
|
+
if (!path9.isAbsolute(entry))
|
|
22237
|
+
return false;
|
|
22238
|
+
if (path9.resolve(entry) !== path9.resolve(path9.join(res.cursorPluginDir, "dist", "cursor-session-start.js"))) {
|
|
22239
|
+
return false;
|
|
22240
|
+
}
|
|
22241
|
+
return validNodeEntry(entry, "node", res.env);
|
|
22222
22242
|
}, checkLauncher = (res) => {
|
|
22223
22243
|
const dev = res.dev;
|
|
22224
22244
|
const hosts = hostsFor(res.host);
|
|
@@ -22234,7 +22254,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
22234
22254
|
const hook = registeredCursorHook(res);
|
|
22235
22255
|
if (hook === "invalid") {
|
|
22236
22256
|
missing.push(`cursor: canonical session-start hook in ${path9.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")}`);
|
|
22237
|
-
} else if (hook !== null && hook !== canonicalCursorHook) {
|
|
22257
|
+
} else if (hook !== null && hook !== canonicalCursorHook && !validLocalDistHook(hook, res)) {
|
|
22238
22258
|
missing.push(`cursor: canonical session-start hook in ${path9.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")} (registered ${hook})`);
|
|
22239
22259
|
}
|
|
22240
22260
|
}
|
|
@@ -24041,8 +24061,13 @@ function sddReviewPackage({
|
|
|
24041
24061
|
const contained = resolveDocsPath({ workspace_root, path: sdd_dir });
|
|
24042
24062
|
if (!contained.ok)
|
|
24043
24063
|
return { error: contained.error };
|
|
24064
|
+
if (base_sha === head_sha) {
|
|
24065
|
+
return {
|
|
24066
|
+
error: `empty commit range (base_sha ${base_sha} === head_sha ${head_sha}): nothing to review`,
|
|
24067
|
+
code: "empty_commit_range"
|
|
24068
|
+
};
|
|
24069
|
+
}
|
|
24044
24070
|
const dir = contained.path;
|
|
24045
|
-
mkdirSync6(dir, { recursive: true });
|
|
24046
24071
|
const base7 = base_sha.slice(0, 7);
|
|
24047
24072
|
const head7 = head_sha.slice(0, 7);
|
|
24048
24073
|
const diffPath = path19.join(dir, `review-${base7}..${head7}.diff`);
|
|
@@ -24052,6 +24077,13 @@ function sddReviewPackage({
|
|
|
24052
24077
|
encoding: "utf8",
|
|
24053
24078
|
stdio: ["pipe", "pipe", "pipe"]
|
|
24054
24079
|
});
|
|
24080
|
+
if (diff.trim() === "") {
|
|
24081
|
+
return {
|
|
24082
|
+
error: `empty commit range (${base_sha}..${head_sha}): diff is empty, nothing to review`,
|
|
24083
|
+
code: "empty_commit_range"
|
|
24084
|
+
};
|
|
24085
|
+
}
|
|
24086
|
+
mkdirSync6(dir, { recursive: true });
|
|
24055
24087
|
writeFileSync5(diffPath, diff, "utf8");
|
|
24056
24088
|
const rel = posix2(path19.relative(contained.base, diffPath));
|
|
24057
24089
|
return { diff_path: rel, base_sha, head_sha, base7, head7 };
|
|
@@ -24069,7 +24101,8 @@ function sddAppendProgress({
|
|
|
24069
24101
|
return { error: contained.error };
|
|
24070
24102
|
const path_ = contained.path;
|
|
24071
24103
|
const trimmed = line.trim();
|
|
24072
|
-
|
|
24104
|
+
const match = PROGRESS_RE.exec(trimmed);
|
|
24105
|
+
if (!match || match[1].toLowerCase() === match[2].toLowerCase()) {
|
|
24073
24106
|
return { error: "invalid progress line format" };
|
|
24074
24107
|
}
|
|
24075
24108
|
if (existsSync11(path_) && statSync6(path_).isDirectory()) {
|
|
@@ -24087,7 +24120,7 @@ var init_sdd = __esm(() => {
|
|
|
24087
24120
|
init_docs_validate();
|
|
24088
24121
|
init_flow_state();
|
|
24089
24122
|
init_docs_layout();
|
|
24090
|
-
PROGRESS_RE = /^Task\s+\d+:\s+complete\s+\(commits\s+[0-9a-f]{7,40}\.\.[0-9a-f]{7,40},/i;
|
|
24123
|
+
PROGRESS_RE = /^Task\s+\d+:\s+complete\s+\(commits\s+([0-9a-f]{7,40})\.\.([0-9a-f]{7,40}),/i;
|
|
24091
24124
|
});
|
|
24092
24125
|
|
|
24093
24126
|
// packages/workit-core/src/core/menu.ts
|
|
@@ -24479,9 +24512,6 @@ var COORDINATOR_RECOVERY_TEXT, CURSOR_SUBAGENT_UNSUPPORTED_TEXT, MENU_CHOICES, e
|
|
|
24479
24512
|
}), resetForPlanDrift = (state) => ({
|
|
24480
24513
|
...state,
|
|
24481
24514
|
plan: { ...state.plan, status: "draft", evidence: null, approved_digest: null },
|
|
24482
|
-
menu: { presented: false, chosen: "", evidence: null },
|
|
24483
|
-
execution: { status: "pending", mode: null, evidence: null },
|
|
24484
|
-
handoff_destination: false,
|
|
24485
24515
|
updated_at: Date.now()
|
|
24486
24516
|
}), driftCodeFor = (root, relPath, storedDigest) => {
|
|
24487
24517
|
if (storedDigest === null)
|
|
@@ -26793,7 +26823,7 @@ function initStatusData(configDirPath = configDir()) {
|
|
|
26793
26823
|
ok: fs5.existsSync(ytJson) && youtrackConfig !== null && !("error" in youtrackConfig),
|
|
26794
26824
|
path: fs5.existsSync(ytJson) ? resolvePath(ytJson) : path28.resolve(ytJson),
|
|
26795
26825
|
config_edit_path: resolvePath(ytJson),
|
|
26796
|
-
fix: "
|
|
26826
|
+
fix: "workit_init_apply action=youtrack_scaffold"
|
|
26797
26827
|
});
|
|
26798
26828
|
const ytTokenPath = youtrackConfig?.tokenFile ?? path28.join(configDirPath, "youtrack.token");
|
|
26799
26829
|
const tokenText = fs5.existsSync(ytTokenPath) ? fs5.readFileSync(ytTokenPath, "utf8").trim() : "";
|
|
@@ -26856,7 +26886,7 @@ function initStatusData(configDirPath = configDir()) {
|
|
|
26856
26886
|
ok: fs5.existsSync(vcsJson) && vcsCfg !== null && !("error" in vcsCfg),
|
|
26857
26887
|
path: fs5.existsSync(vcsJson) ? resolvePath(vcsJson) : path28.resolve(vcsJson),
|
|
26858
26888
|
config_edit_path: resolvePath(vcsJson),
|
|
26859
|
-
fix: "
|
|
26889
|
+
fix: "workit_init_apply action=vcs_scaffold"
|
|
26860
26890
|
});
|
|
26861
26891
|
const provActive = vcsCfg && !("error" in vcsCfg) ? vcsCfg.provider : null;
|
|
26862
26892
|
const tokenItem = (tid, label, rawPath, providerKey) => {
|
|
@@ -27924,7 +27954,7 @@ var init_server3 = __esm(async () => {
|
|
|
27924
27954
|
}
|
|
27925
27955
|
return jsonResult(withWorkspace(workspace_root, payload));
|
|
27926
27956
|
});
|
|
27927
|
-
registerTool("
|
|
27957
|
+
registerTool("workit_init_status", {
|
|
27928
27958
|
description: "Check workit setup (MCP deps, YouTrack config, token)",
|
|
27929
27959
|
inputSchema: {}
|
|
27930
27960
|
}, async () => {
|
|
@@ -27933,7 +27963,7 @@ var init_server3 = __esm(async () => {
|
|
|
27933
27963
|
return jsonResult({ error: data.error });
|
|
27934
27964
|
return jsonResult(data);
|
|
27935
27965
|
});
|
|
27936
|
-
registerTool("
|
|
27966
|
+
registerTool("workit_status", {
|
|
27937
27967
|
description: "Full health check: MCP deps, config files, YouTrack API verify. Use after editing token file.",
|
|
27938
27968
|
inputSchema: {}
|
|
27939
27969
|
}, async () => {
|
|
@@ -27942,7 +27972,7 @@ var init_server3 = __esm(async () => {
|
|
|
27942
27972
|
return jsonResult({ error: data.error });
|
|
27943
27973
|
return jsonResult(data);
|
|
27944
27974
|
});
|
|
27945
|
-
registerTool("
|
|
27975
|
+
registerTool("workit_init_apply", {
|
|
27946
27976
|
description: "Apply init action. Requires confirmed: true. Token is NOT accepted here — user edits token file locally.",
|
|
27947
27977
|
inputSchema: {
|
|
27948
27978
|
action: exports_external.enum([
|
|
@@ -28377,7 +28407,7 @@ import path29 from "node:path";
|
|
|
28377
28407
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
28378
28408
|
var mcpDir = path29.dirname(fileURLToPath2(import.meta.url));
|
|
28379
28409
|
var pluginDir = path29.resolve(mcpDir, "..");
|
|
28380
|
-
var marker = path29.join(pluginDir, ".
|
|
28410
|
+
var marker = path29.join(pluginDir, ".workit-root");
|
|
28381
28411
|
var resolveRoot = () => {
|
|
28382
28412
|
if (process.env.WORKFLOW_TOOLKIT_ROOT && existsSync19(path29.join(process.env.WORKFLOW_TOOLKIT_ROOT, "scripts"))) {
|
|
28383
28413
|
return process.env.WORKFLOW_TOOLKIT_ROOT;
|
package/hooks/hooks-cursor.json
CHANGED
package/mcp.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"workit": {
|
|
4
4
|
"command": "npx",
|
|
5
|
-
"args": ["-y", "--package=@brainervirus/workit-cursor@
|
|
5
|
+
"args": ["-y", "--prefer-online", "--package=@brainervirus/workit-cursor@latest", "workit-cursor-mcp", "${workspaceFolder}"]
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cursor",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit Cursor plugin: MCP server, hooks, rules, marketplace manifest (thin over @brainervirus/workit-core)",
|
|
6
6
|
"keywords": [
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"build": "bun scripts/build.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@brainervirus/workit-core": "^0.8.
|
|
42
|
+
"@brainervirus/workit-core": "^0.8.7",
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
44
44
|
"zod": "^3.24.0"
|
|
45
45
|
},
|
|
@@ -23,6 +23,8 @@ The pasted prompt includes instructions to call `workflow_sdd_context`, **Cursor
|
|
|
23
23
|
|
|
24
24
|
`workflow_handoff_prompt` also returns `tasks[]`, `branch`, `sdd_dir`, `completed_task_ids`, and `todos` for same-session MCP use — not copy-paste transport.
|
|
25
25
|
|
|
26
|
+
A destination run that executes the plan must still end with `workflow_plan_complete` once the SDD ledger is complete and repository verification passes, and never finish the run while the plan is still `active`.
|
|
27
|
+
|
|
26
28
|
## Output (success)
|
|
27
29
|
|
|
28
30
|
When the tool returns `{ prompt }`, output **only** one fenced code block containing `prompt` verbatim. No preamble, no explanation outside the fence.
|
|
@@ -37,4 +37,8 @@ Announce: "Using implement + inline."
|
|
|
37
37
|
|
|
38
38
|
Follow the contract verbatim. Keep TodoWrite `in_progress`/`completed` in sync each task. At verify/commit phase use `workflow_verify` and `workflow_git_context` MCP tools.
|
|
39
39
|
|
|
40
|
+
Each task lands exactly one contiguous non-empty commit range (`base..head`): fix rounds append commits to that range and never rewrite/amend an active review range; each progress line records the task's real base..head shas.
|
|
41
|
+
|
|
40
42
|
Do not emit a handoff fence — this is in-session execution.
|
|
43
|
+
|
|
44
|
+
**Mandatory:** end the run by calling MCP `workflow_plan_complete` after the final task once the SDD ledger is complete (all task IDs appended) and `workflow_verify` passes — a complete ledger and green verification are the tool's gates. Never finish the run while the plan is still `active`.
|
package/skills/wk-init/SKILL.md
CHANGED
|
@@ -12,7 +12,7 @@ Scaffold config via MCP. **Never paste API tokens in chat.**
|
|
|
12
12
|
|
|
13
13
|
## Step 1 — Status (required)
|
|
14
14
|
|
|
15
|
-
Call MCP `
|
|
15
|
+
Call MCP `workit_init_status`. Show `items[]` in English.
|
|
16
16
|
|
|
17
17
|
### YouTrack settings (when `youtrack_config` present)
|
|
18
18
|
|
|
@@ -42,11 +42,11 @@ Call MCP `workflow_toolkit_init_status`. Show `items[]` in English.
|
|
|
42
42
|
|
|
43
43
|
### mcp_deps
|
|
44
44
|
|
|
45
|
-
Native `AskQuestion` asks whether to install MCP dependencies → on yes: `
|
|
45
|
+
Native `AskQuestion` asks whether to install MCP dependencies → on yes: `workit_init_apply` action=`npm_install` confirmed=`true`
|
|
46
46
|
|
|
47
47
|
### YouTrack scaffold
|
|
48
48
|
|
|
49
|
-
Native `AskQuestion` asks whether to create the YouTrack scaffold → on yes: `
|
|
49
|
+
Native `AskQuestion` asks whether to create the YouTrack scaffold → on yes: `workit_init_apply` action=`youtrack_scaffold` confirmed=`true`
|
|
50
50
|
|
|
51
51
|
### VCS scaffold (GitLab + GitHub token files)
|
|
52
52
|
|
|
@@ -54,7 +54,7 @@ Only when `items[vcs_json].ok` is **false**:
|
|
|
54
54
|
|
|
55
55
|
1. Native `AskQuestion` asks for GitLab or GitHub → remember `provider` (`gitlab` | `github`).
|
|
56
56
|
2. Native `AskQuestion` asks `Create vcs.json and token placeholders for <provider>?`
|
|
57
|
-
→ on yes: `
|
|
57
|
+
→ on yes: `workit_init_apply` action=`vcs_scaffold` confirmed=`true` **`vcs_provider=<chosen provider>`**
|
|
58
58
|
|
|
59
59
|
Both `gitlab.token` and `github.token` are always created (switch later by editing `provider` in `vcs.json`). Tell the user which token file is **active** for `/wk-pr` based on the chosen provider.
|
|
60
60
|
|
|
@@ -103,5 +103,5 @@ For the **active** provider (`vcs_config.provider`), show from `vcs_config.token
|
|
|
103
103
|
## Rules
|
|
104
104
|
|
|
105
105
|
- Never ask for or accept tokens in chat.
|
|
106
|
-
- Mutations only via `
|
|
106
|
+
- Mutations only via `workit_init_apply` with `confirmed: true`.
|
|
107
107
|
- Verification is **`/wk-status`** only — not part of init.
|
|
@@ -18,7 +18,7 @@ Post a Spanish comment and log time on a **task** issue (not the meeting issue).
|
|
|
18
18
|
|
|
19
19
|
## Step 0 — Toolkit ready
|
|
20
20
|
|
|
21
|
-
If unsure, call `
|
|
21
|
+
If unsure, call `workit_status`. Stop if `ready: false`.
|
|
22
22
|
|
|
23
23
|
## Step 1 — Issue (required)
|
|
24
24
|
|
|
@@ -12,7 +12,7 @@ Log meeting time to a **meeting issue** from config. **Never post a comment.**
|
|
|
12
12
|
|
|
13
13
|
## Step 0 — Toolkit ready
|
|
14
14
|
|
|
15
|
-
If unsure, call `
|
|
15
|
+
If unsure, call `workit_status`. Stop if `ready: false`.
|
|
16
16
|
|
|
17
17
|
## Step 1 — Context (required)
|
|
18
18
|
|
|
@@ -12,7 +12,7 @@ Deterministic health check. **Tools only — no manual git/curl.**
|
|
|
12
12
|
|
|
13
13
|
## Step 1 — Full status (required)
|
|
14
14
|
|
|
15
|
-
Call MCP `
|
|
15
|
+
Call MCP `workit_status` once.
|
|
16
16
|
|
|
17
17
|
Use the return value as ground truth. Do not infer state yourself.
|
|
18
18
|
|
|
@@ -80,6 +80,6 @@ Use `items[youtrack_token].token_create_url` / `token_edit_path`, or top-level `
|
|
|
80
80
|
|
|
81
81
|
## Rules
|
|
82
82
|
|
|
83
|
-
- Do not call YouTrack HTTP directly — `
|
|
83
|
+
- Do not call YouTrack HTTP directly — `workit_status` includes verify.
|
|
84
84
|
- Do not ask user to paste token — point them to edit the token file if `placeholder: true`.
|
|
85
85
|
- Optional: `workflow_youtrack_verify_token` only if user asks to re-test API alone.
|
|
@@ -63,6 +63,7 @@ digraph process {
|
|
|
63
63
|
"Read plan, note context and global constraints, create todos" [shape=box];
|
|
64
64
|
"More tasks remain?" [shape=diamond];
|
|
65
65
|
"Dispatch final code reviewer subagent (../requesting-code-review/code-reviewer.md)" [shape=box];
|
|
66
|
+
"Run verification, then workflow_plan_complete once the ledger is complete and verification passes" [shape=box];
|
|
66
67
|
"Use superpowers:finishing-a-development-branch" [shape=box style=filled fillcolor=lightgreen];
|
|
67
68
|
|
|
68
69
|
"Read plan, note context and global constraints, create todos" -> "Dispatch implementer subagent (./implementer-prompt.md)";
|
|
@@ -78,10 +79,13 @@ digraph process {
|
|
|
78
79
|
"Mark task complete in todo list and progress ledger" -> "More tasks remain?";
|
|
79
80
|
"More tasks remain?" -> "Dispatch implementer subagent (./implementer-prompt.md)" [label="yes"];
|
|
80
81
|
"More tasks remain?" -> "Dispatch final code reviewer subagent (../requesting-code-review/code-reviewer.md)" [label="no"];
|
|
81
|
-
"Dispatch final code reviewer subagent (../requesting-code-review/code-reviewer.md)" -> "
|
|
82
|
+
"Dispatch final code reviewer subagent (../requesting-code-review/code-reviewer.md)" -> "Run verification, then workflow_plan_complete once the ledger is complete and verification passes";
|
|
83
|
+
"Run verification, then workflow_plan_complete once the ledger is complete and verification passes" -> "Use superpowers:finishing-a-development-branch";
|
|
82
84
|
}
|
|
83
85
|
```
|
|
84
86
|
|
|
87
|
+
**Mandatory completion:** after the final whole-branch review, run repository verification. Once the SDD ledger is complete and verification passes, end the run by calling `workflow_plan_complete` (or the CLI `workit flow complete`) — a complete ledger and green verification are the tool's gates. Never finish while the plan is still `active`.
|
|
88
|
+
|
|
85
89
|
## Pre-Flight Plan Review
|
|
86
90
|
|
|
87
91
|
Before dispatching Task 1, scan the plan once for conflicts:
|
|
@@ -257,6 +261,10 @@ a ledger file, not only in todos.
|
|
|
257
261
|
- When a task's review comes back clean, append one line to the ledger in
|
|
258
262
|
the same message as your other bookkeeping:
|
|
259
263
|
`Task N: complete (commits <base7>..<head7>, review clean)`.
|
|
264
|
+
- Each task produces exactly one contiguous non-empty commit range: fix
|
|
265
|
+
rounds append commits to it, never amend or rewrite an active review
|
|
266
|
+
range, and the ledger progress line records the task's real base..head
|
|
267
|
+
shas.
|
|
260
268
|
- The ledger is your recovery map: the commits it names exist in git even
|
|
261
269
|
when your context no longer remembers creating them. After compaction,
|
|
262
270
|
trust the ledger and `git log` over your own recollection.
|