@brainervirus/workit-cursor 8.31.1 → 8.33.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 +27 -3
- package/dist/mcp-server.js +44 -8
- package/dist/workit-hook.js +27 -3
- package/package.json +3 -3
|
@@ -8261,6 +8261,7 @@ var init_workspaces = __esm(() => {
|
|
|
8261
8261
|
verification: _enum(["proportional", "self", "independent"]).optional(),
|
|
8262
8262
|
delegation: unknown().optional(),
|
|
8263
8263
|
trailers: boolean2().optional(),
|
|
8264
|
+
deleteBranch: boolean2().optional(),
|
|
8264
8265
|
liveSessionGuard: boolean2().optional(),
|
|
8265
8266
|
fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
|
|
8266
8267
|
models: object({ roles: unknown().optional() }).passthrough().optional(),
|
|
@@ -17848,7 +17849,8 @@ var sessionMarkerFile = (input, session, store) => {
|
|
|
17848
17849
|
loaded: list2(value.loaded),
|
|
17849
17850
|
raw: list2(value.raw),
|
|
17850
17851
|
stops: list2(value.stops),
|
|
17851
|
-
judges: list2(value.judges)
|
|
17852
|
+
judges: list2(value.judges),
|
|
17853
|
+
model: typeof value.model === "string" ? value.model : null
|
|
17852
17854
|
};
|
|
17853
17855
|
} catch {
|
|
17854
17856
|
return { ...EMPTY };
|
|
@@ -17887,10 +17889,28 @@ var sessionMarkerFile = (input, session, store) => {
|
|
|
17887
17889
|
const rest = marker.judges.filter((id) => id !== agentId);
|
|
17888
17890
|
return { ...marker, judges: running ? [...rest, agentId] : rest };
|
|
17889
17891
|
});
|
|
17892
|
+
}, modelSwitchedOnDisk = (input) => {
|
|
17893
|
+
const session = input.session.id;
|
|
17894
|
+
const model = input.model;
|
|
17895
|
+
const file = session && model ? sessionMarkerFile(input, session) : null;
|
|
17896
|
+
if (!file || !model)
|
|
17897
|
+
return false;
|
|
17898
|
+
const previous = readSessionMarker(file).model;
|
|
17899
|
+
if (previous === model)
|
|
17900
|
+
return false;
|
|
17901
|
+
updateSessionMarker(file, (marker) => ({ ...marker, model }));
|
|
17902
|
+
return previous !== null;
|
|
17890
17903
|
};
|
|
17891
17904
|
var init_session_marker = __esm(() => {
|
|
17892
17905
|
init_paths();
|
|
17893
|
-
EMPTY = {
|
|
17906
|
+
EMPTY = {
|
|
17907
|
+
nudged: [],
|
|
17908
|
+
loaded: [],
|
|
17909
|
+
raw: [],
|
|
17910
|
+
stops: [],
|
|
17911
|
+
judges: [],
|
|
17912
|
+
model: null
|
|
17913
|
+
};
|
|
17894
17914
|
});
|
|
17895
17915
|
|
|
17896
17916
|
// packages/workit-core/src/hooks/shell-words.ts
|
|
@@ -22642,7 +22662,9 @@ function decide(input, deps) {
|
|
|
22642
22662
|
if (!usable2(descriptor.context.perTurn))
|
|
22643
22663
|
return NONE6;
|
|
22644
22664
|
const current = turnContextText(input, descriptor);
|
|
22645
|
-
const
|
|
22665
|
+
const turn = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
|
|
22666
|
+
const text = input.model && modelSwitchedOnDisk(input) ? [invariantBootstrap(), turn].filter(Boolean).join(`
|
|
22667
|
+
`) : turn;
|
|
22646
22668
|
return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
|
|
22647
22669
|
}
|
|
22648
22670
|
case "shell.pre": {
|
|
@@ -22818,6 +22840,7 @@ var init_handle = __esm(() => {
|
|
|
22818
22840
|
init_spawn_gate();
|
|
22819
22841
|
init_standing();
|
|
22820
22842
|
init_session_marker();
|
|
22843
|
+
init_methods();
|
|
22821
22844
|
init_stop();
|
|
22822
22845
|
init_live_session();
|
|
22823
22846
|
init_write_gate();
|
|
@@ -23492,6 +23515,7 @@ var init_codex = __esm(() => {
|
|
|
23492
23515
|
},
|
|
23493
23516
|
permissionMode: input.permission_mode,
|
|
23494
23517
|
transcriptPath: input.transcript_path,
|
|
23518
|
+
model: input.model,
|
|
23495
23519
|
event: protocolEvent(input)
|
|
23496
23520
|
}
|
|
23497
23521
|
};
|
package/dist/mcp-server.js
CHANGED
|
@@ -16256,10 +16256,11 @@ function invalidOperation(family, input, error) {
|
|
|
16256
16256
|
const request = isObject2(input) ? input : {};
|
|
16257
16257
|
const action = typeof request.action === "string" ? request.action : "";
|
|
16258
16258
|
const actions = OPERATION_ACTIONS[family];
|
|
16259
|
-
if (!actions.includes(action))
|
|
16260
|
-
|
|
16261
|
-
|
|
16262
|
-
});
|
|
16259
|
+
if (!actions.includes(action)) {
|
|
16260
|
+
const common = actions.find((name) => READ_ONLY_ACTIONS.has(name)) ?? actions[0];
|
|
16261
|
+
const example = JSON.stringify(exampleOperation(family, common));
|
|
16262
|
+
return failure2("invalid_input", `${family}: action must be one of ${oneOf(actions)}. Example: ${example}`, { fields: [{ path: "action", reason: `got ${JSON.stringify(request.action ?? null)}` }] });
|
|
16263
|
+
}
|
|
16263
16264
|
const own = actionKeys(family, action);
|
|
16264
16265
|
const fields = [];
|
|
16265
16266
|
const sentence = [];
|
|
@@ -17331,6 +17332,7 @@ var workspaceConfigSchema = object2({
|
|
|
17331
17332
|
verification: _enum(["proportional", "self", "independent"]).optional(),
|
|
17332
17333
|
delegation: unknown().optional(),
|
|
17333
17334
|
trailers: boolean2().optional(),
|
|
17335
|
+
deleteBranch: boolean2().optional(),
|
|
17334
17336
|
liveSessionGuard: boolean2().optional(),
|
|
17335
17337
|
fanout: object2({ tierModels: unknown().optional() }).passthrough().optional(),
|
|
17336
17338
|
models: object2({ roles: unknown().optional() }).passthrough().optional(),
|
|
@@ -27733,6 +27735,38 @@ function run2(root, executable, args, env = {}) {
|
|
|
27733
27735
|
};
|
|
27734
27736
|
}
|
|
27735
27737
|
|
|
27738
|
+
// packages/workit-core/src/hooks/repeat-failure.ts
|
|
27739
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
27740
|
+
var SAME_CALL_FAILED = "Same call failed twice:";
|
|
27741
|
+
var MAX_SESSIONS = 256;
|
|
27742
|
+
var stable = (value) => JSON.stringify(value, (_key, entry) => entry && typeof entry === "object" && !Array.isArray(entry) ? Object.fromEntries(Object.entries(entry).toSorted(([a], [b]) => a.localeCompare(b))) : entry) ?? "null";
|
|
27743
|
+
var hashOf = (call) => createHash11("sha256").update(call).digest("hex").slice(0, 32);
|
|
27744
|
+
var record3 = (memo, sessionId, call, failed, next) => {
|
|
27745
|
+
const previous = memo.get(sessionId);
|
|
27746
|
+
memo.delete(sessionId);
|
|
27747
|
+
if (!failed)
|
|
27748
|
+
return null;
|
|
27749
|
+
const hash = hashOf(call);
|
|
27750
|
+
memo.set(sessionId, hash);
|
|
27751
|
+
if (memo.size > MAX_SESSIONS)
|
|
27752
|
+
memo.delete(memo.keys().next().value);
|
|
27753
|
+
return previous === hash && next ? `${SAME_CALL_FAILED} ${next}` : null;
|
|
27754
|
+
};
|
|
27755
|
+
var isFailure = (result) => result !== null && typeof result === "object" && result.ok === false && typeof result.error === "string";
|
|
27756
|
+
var correctedPayload = (tool, result) => {
|
|
27757
|
+
const example = /Example: (\{.*\})\s*$/.exec(result.error)?.[1];
|
|
27758
|
+
if (example)
|
|
27759
|
+
return `${tool} ${example}`;
|
|
27760
|
+
const guidance = result.details?.guidance;
|
|
27761
|
+
return typeof guidance === "string" && guidance ? guidance : null;
|
|
27762
|
+
};
|
|
27763
|
+
var escalateToolFailure = (memo, sessionId, tool, input, result) => {
|
|
27764
|
+
const failed = isFailure(result);
|
|
27765
|
+
const line = record3(memo, sessionId, `tool\x00${tool}\x00${stable(input)}`, failed, failed ? correctedPayload(tool, result) : null);
|
|
27766
|
+
return line && failed ? { ...result, error: `${result.error}
|
|
27767
|
+
${line}` } : result;
|
|
27768
|
+
};
|
|
27769
|
+
|
|
27736
27770
|
// packages/workit-mcp/src/server.ts
|
|
27737
27771
|
class McpCapabilityUnavailableError extends Error {
|
|
27738
27772
|
capability;
|
|
@@ -27828,8 +27862,8 @@ var sanitizeFailure = (result, workspaceRoot) => {
|
|
|
27828
27862
|
};
|
|
27829
27863
|
return sanitize(result);
|
|
27830
27864
|
};
|
|
27831
|
-
var resultForClient = (result, workspaceRoot) => {
|
|
27832
|
-
const safe = sanitizeFailure(result, workspaceRoot);
|
|
27865
|
+
var resultForClient = (result, workspaceRoot, escalate = (safe) => safe) => {
|
|
27866
|
+
const safe = escalate(sanitizeFailure(result, workspaceRoot));
|
|
27833
27867
|
return {
|
|
27834
27868
|
content: [{ type: "text", text: JSON.stringify(safe) }],
|
|
27835
27869
|
structuredContent: safe,
|
|
@@ -27866,6 +27900,7 @@ function createMcpServer(host, contextProvider) {
|
|
|
27866
27900
|
path23.join(here, "..", "..", "workit-core", "src", "core", "task-engine.ts")
|
|
27867
27901
|
].filter((file) => existsSync9(file)));
|
|
27868
27902
|
let staleWarned = false;
|
|
27903
|
+
const failures = new Map;
|
|
27869
27904
|
const server = new Server({ name: "workit", version: VERSION }, { capabilities: { tools: {}, resources: {} } });
|
|
27870
27905
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
27871
27906
|
let attested = false;
|
|
@@ -27988,9 +28023,10 @@ function createMcpServer(host, contextProvider) {
|
|
|
27988
28023
|
details: { operation: family }
|
|
27989
28024
|
}, workspaceRoot);
|
|
27990
28025
|
}
|
|
28026
|
+
const escalate = (safe) => escalateToolFailure(failures, context.caller.actor || "mcp", toolName, request.params.arguments, safe);
|
|
27991
28027
|
const parsed = parseAdvertisedOperation(family, request.params.arguments, host);
|
|
27992
28028
|
if (!parsed.ok)
|
|
27993
|
-
return resultForClient(parsed, workspaceRoot);
|
|
28029
|
+
return resultForClient(parsed, workspaceRoot, escalate);
|
|
27994
28030
|
if (context.callerAttested !== true && requiresCallerIdentity(parsed.data))
|
|
27995
28031
|
return resultForClient({
|
|
27996
28032
|
ok: false,
|
|
@@ -28002,7 +28038,7 @@ function createMcpServer(host, contextProvider) {
|
|
|
28002
28038
|
const core = new WorkitCore(new TaskStore(context.root), context);
|
|
28003
28039
|
const run = core[family];
|
|
28004
28040
|
const result = run.call(core, parsed.data);
|
|
28005
|
-
return resultForClient(family === "task" && context.callerAttested !== true ? briefInspectResult(parsed.data, result) : result, workspaceRoot);
|
|
28041
|
+
return resultForClient(family === "task" && context.callerAttested !== true ? briefInspectResult(parsed.data, result) : result, workspaceRoot, escalate);
|
|
28006
28042
|
} catch (error) {
|
|
28007
28043
|
return thrownResult(toolName, error, workspaceRoot);
|
|
28008
28044
|
}
|
package/dist/workit-hook.js
CHANGED
|
@@ -7861,6 +7861,7 @@ var workspaceConfigSchema = object({
|
|
|
7861
7861
|
verification: _enum(["proportional", "self", "independent"]).optional(),
|
|
7862
7862
|
delegation: unknown().optional(),
|
|
7863
7863
|
trailers: boolean2().optional(),
|
|
7864
|
+
deleteBranch: boolean2().optional(),
|
|
7864
7865
|
liveSessionGuard: boolean2().optional(),
|
|
7865
7866
|
fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
|
|
7866
7867
|
models: object({ roles: unknown().optional() }).passthrough().optional(),
|
|
@@ -17904,7 +17905,14 @@ var sessionMarkerFile = (input, session, store) => {
|
|
|
17904
17905
|
return path21.join(dir, "hooks", `skills-${name}.json`);
|
|
17905
17906
|
};
|
|
17906
17907
|
var list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
17907
|
-
var EMPTY = {
|
|
17908
|
+
var EMPTY = {
|
|
17909
|
+
nudged: [],
|
|
17910
|
+
loaded: [],
|
|
17911
|
+
raw: [],
|
|
17912
|
+
stops: [],
|
|
17913
|
+
judges: [],
|
|
17914
|
+
model: null
|
|
17915
|
+
};
|
|
17908
17916
|
var readRaw = (file) => {
|
|
17909
17917
|
try {
|
|
17910
17918
|
return fs16.readFileSync(file, "utf8");
|
|
@@ -17920,7 +17928,8 @@ var parseMarker = (text) => {
|
|
|
17920
17928
|
loaded: list2(value.loaded),
|
|
17921
17929
|
raw: list2(value.raw),
|
|
17922
17930
|
stops: list2(value.stops),
|
|
17923
|
-
judges: list2(value.judges)
|
|
17931
|
+
judges: list2(value.judges),
|
|
17932
|
+
model: typeof value.model === "string" ? value.model : null
|
|
17924
17933
|
};
|
|
17925
17934
|
} catch {
|
|
17926
17935
|
return { ...EMPTY };
|
|
@@ -17965,6 +17974,18 @@ var trackJudge = (input, agentId, running) => {
|
|
|
17965
17974
|
return { ...marker, judges: running ? [...rest, agentId] : rest };
|
|
17966
17975
|
});
|
|
17967
17976
|
};
|
|
17977
|
+
var modelSwitchedOnDisk = (input) => {
|
|
17978
|
+
const session = input.session.id;
|
|
17979
|
+
const model = input.model;
|
|
17980
|
+
const file = session && model ? sessionMarkerFile(input, session) : null;
|
|
17981
|
+
if (!file || !model)
|
|
17982
|
+
return false;
|
|
17983
|
+
const previous = readSessionMarker(file).model;
|
|
17984
|
+
if (previous === model)
|
|
17985
|
+
return false;
|
|
17986
|
+
updateSessionMarker(file, (marker) => ({ ...marker, model }));
|
|
17987
|
+
return previous !== null;
|
|
17988
|
+
};
|
|
17968
17989
|
|
|
17969
17990
|
// packages/workit-core/src/hooks/shell-words.ts
|
|
17970
17991
|
class ShellAnalysisError extends Error {
|
|
@@ -22907,7 +22928,9 @@ function decide(input, deps) {
|
|
|
22907
22928
|
if (!usable2(descriptor.context.perTurn))
|
|
22908
22929
|
return NONE6;
|
|
22909
22930
|
const current = turnContextText(input, descriptor);
|
|
22910
|
-
const
|
|
22931
|
+
const turn = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
|
|
22932
|
+
const text = input.model && modelSwitchedOnDisk(input) ? [invariantBootstrap(), turn].filter(Boolean).join(`
|
|
22933
|
+
`) : turn;
|
|
22911
22934
|
return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
|
|
22912
22935
|
}
|
|
22913
22936
|
case "shell.pre": {
|
|
@@ -23716,6 +23739,7 @@ var codexAdapter = {
|
|
|
23716
23739
|
},
|
|
23717
23740
|
permissionMode: input.permission_mode,
|
|
23718
23741
|
transcriptPath: input.transcript_path,
|
|
23742
|
+
model: input.model,
|
|
23719
23743
|
event: protocolEvent(input)
|
|
23720
23744
|
}
|
|
23721
23745
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cursor",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.33.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.
|
|
50
|
-
"@brainervirus/workit-mcp": "^8.
|
|
49
|
+
"@brainervirus/workit-core": "^8.33.0",
|
|
50
|
+
"@brainervirus/workit-mcp": "^8.33.0"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=24"
|