@brainervirus/workit-codex 8.32.0 → 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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workit",
3
- "version": "8.32.0",
3
+ "version": "8.33.0",
4
4
  "description": "Adaptive engineering workflow rails for Codex",
5
5
  "author": {
6
6
  "name": "BrainerVirus"
@@ -13875,10 +13875,11 @@ function invalidOperation(family, input, error) {
13875
13875
  const request = isObject2(input) ? input : {};
13876
13876
  const action = typeof request.action === "string" ? request.action : "";
13877
13877
  const actions = OPERATION_ACTIONS[family];
13878
- if (!actions.includes(action))
13879
- return failure2("invalid_input", `${family}: action must be one of ${oneOf(actions)}`, {
13880
- fields: [{ path: "action", reason: `got ${JSON.stringify(request.action ?? null)}` }]
13881
- });
13878
+ if (!actions.includes(action)) {
13879
+ const common = actions.find((name) => READ_ONLY_ACTIONS.has(name)) ?? actions[0];
13880
+ const example = JSON.stringify(exampleOperation(family, common));
13881
+ return failure2("invalid_input", `${family}: action must be one of ${oneOf(actions)}. Example: ${example}`, { fields: [{ path: "action", reason: `got ${JSON.stringify(request.action ?? null)}` }] });
13882
+ }
13882
13883
  const own = actionKeys(family, action);
13883
13884
  const fields = [];
13884
13885
  const sentence = [];
@@ -27770,6 +27771,40 @@ class StdioServerTransport {
27770
27771
 
27771
27772
  // packages/workit-mcp/src/server.ts
27772
27773
  import { fileURLToPath as fileURLToPath2 } from "node:url";
27774
+
27775
+ // packages/workit-core/src/hooks/repeat-failure.ts
27776
+ import { createHash as createHash11 } from "node:crypto";
27777
+ var SAME_CALL_FAILED = "Same call failed twice:";
27778
+ var MAX_SESSIONS = 256;
27779
+ 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";
27780
+ var hashOf = (call) => createHash11("sha256").update(call).digest("hex").slice(0, 32);
27781
+ var record3 = (memo, sessionId, call, failed, next) => {
27782
+ const previous = memo.get(sessionId);
27783
+ memo.delete(sessionId);
27784
+ if (!failed)
27785
+ return null;
27786
+ const hash = hashOf(call);
27787
+ memo.set(sessionId, hash);
27788
+ if (memo.size > MAX_SESSIONS)
27789
+ memo.delete(memo.keys().next().value);
27790
+ return previous === hash && next ? `${SAME_CALL_FAILED} ${next}` : null;
27791
+ };
27792
+ var isFailure = (result) => result !== null && typeof result === "object" && result.ok === false && typeof result.error === "string";
27793
+ var correctedPayload = (tool, result) => {
27794
+ const example = /Example: (\{.*\})\s*$/.exec(result.error)?.[1];
27795
+ if (example)
27796
+ return `${tool} ${example}`;
27797
+ const guidance = result.details?.guidance;
27798
+ return typeof guidance === "string" && guidance ? guidance : null;
27799
+ };
27800
+ var escalateToolFailure = (memo, sessionId, tool, input, result) => {
27801
+ const failed = isFailure(result);
27802
+ const line = record3(memo, sessionId, `tool\x00${tool}\x00${stable(input)}`, failed, failed ? correctedPayload(tool, result) : null);
27803
+ return line && failed ? { ...result, error: `${result.error}
27804
+ ${line}` } : result;
27805
+ };
27806
+
27807
+ // packages/workit-mcp/src/server.ts
27773
27808
  class McpCapabilityUnavailableError extends Error {
27774
27809
  capability;
27775
27810
  constructor(capability) {
@@ -27864,8 +27899,8 @@ var sanitizeFailure = (result, workspaceRoot) => {
27864
27899
  };
27865
27900
  return sanitize(result);
27866
27901
  };
27867
- var resultForClient = (result, workspaceRoot) => {
27868
- const safe = sanitizeFailure(result, workspaceRoot);
27902
+ var resultForClient = (result, workspaceRoot, escalate = (safe) => safe) => {
27903
+ const safe = escalate(sanitizeFailure(result, workspaceRoot));
27869
27904
  return {
27870
27905
  content: [{ type: "text", text: JSON.stringify(safe) }],
27871
27906
  structuredContent: safe,
@@ -27902,6 +27937,7 @@ function createMcpServer(host, contextProvider) {
27902
27937
  path23.join(here, "..", "..", "workit-core", "src", "core", "task-engine.ts")
27903
27938
  ].filter((file) => existsSync9(file)));
27904
27939
  let staleWarned = false;
27940
+ const failures = new Map;
27905
27941
  const server = new Server({ name: "workit", version: VERSION }, { capabilities: { tools: {}, resources: {} } });
27906
27942
  server.setRequestHandler(ListToolsRequestSchema, async () => {
27907
27943
  let attested = false;
@@ -28024,9 +28060,10 @@ function createMcpServer(host, contextProvider) {
28024
28060
  details: { operation: family }
28025
28061
  }, workspaceRoot);
28026
28062
  }
28063
+ const escalate = (safe) => escalateToolFailure(failures, context.caller.actor || "mcp", toolName, request.params.arguments, safe);
28027
28064
  const parsed = parseAdvertisedOperation(family, request.params.arguments, host);
28028
28065
  if (!parsed.ok)
28029
- return resultForClient(parsed, workspaceRoot);
28066
+ return resultForClient(parsed, workspaceRoot, escalate);
28030
28067
  if (context.callerAttested !== true && requiresCallerIdentity(parsed.data))
28031
28068
  return resultForClient({
28032
28069
  ok: false,
@@ -28038,7 +28075,7 @@ function createMcpServer(host, contextProvider) {
28038
28075
  const core = new WorkitCore(new TaskStore(context.root), context);
28039
28076
  const run = core[family];
28040
28077
  const result = run.call(core, parsed.data);
28041
- return resultForClient(family === "task" && context.callerAttested !== true ? briefInspectResult(parsed.data, result) : result, workspaceRoot);
28078
+ return resultForClient(family === "task" && context.callerAttested !== true ? briefInspectResult(parsed.data, result) : result, workspaceRoot, escalate);
28042
28079
  } catch (error) {
28043
28080
  return thrownResult(toolName, error, workspaceRoot);
28044
28081
  }
@@ -17628,7 +17628,14 @@ var sessionMarkerFile = (input, session, store) => {
17628
17628
  return path19.join(dir, "hooks", `skills-${name}.json`);
17629
17629
  };
17630
17630
  var list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
17631
- var EMPTY = { nudged: [], loaded: [], raw: [], stops: [], judges: [] };
17631
+ var EMPTY = {
17632
+ nudged: [],
17633
+ loaded: [],
17634
+ raw: [],
17635
+ stops: [],
17636
+ judges: [],
17637
+ model: null
17638
+ };
17632
17639
  var readRaw = (file) => {
17633
17640
  try {
17634
17641
  return fs14.readFileSync(file, "utf8");
@@ -17644,7 +17651,8 @@ var parseMarker = (text) => {
17644
17651
  loaded: list2(value.loaded),
17645
17652
  raw: list2(value.raw),
17646
17653
  stops: list2(value.stops),
17647
- judges: list2(value.judges)
17654
+ judges: list2(value.judges),
17655
+ model: typeof value.model === "string" ? value.model : null
17648
17656
  };
17649
17657
  } catch {
17650
17658
  return { ...EMPTY };
@@ -17689,6 +17697,18 @@ var trackJudge = (input, agentId, running) => {
17689
17697
  return { ...marker, judges: running ? [...rest, agentId] : rest };
17690
17698
  });
17691
17699
  };
17700
+ var modelSwitchedOnDisk = (input) => {
17701
+ const session = input.session.id;
17702
+ const model = input.model;
17703
+ const file = session && model ? sessionMarkerFile(input, session) : null;
17704
+ if (!file || !model)
17705
+ return false;
17706
+ const previous = readSessionMarker(file).model;
17707
+ if (previous === model)
17708
+ return false;
17709
+ updateSessionMarker(file, (marker) => ({ ...marker, model }));
17710
+ return previous !== null;
17711
+ };
17692
17712
 
17693
17713
  // packages/workit-core/src/hooks/shell-words.ts
17694
17714
  class ShellAnalysisError extends Error {
@@ -22570,7 +22590,9 @@ function decide(input, deps) {
22570
22590
  if (!usable2(descriptor.context.perTurn))
22571
22591
  return NONE6;
22572
22592
  const current = turnContextText(input, descriptor);
22573
- const text = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
22593
+ const turn = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
22594
+ const text = input.model && modelSwitchedOnDisk(input) ? [invariantBootstrap(), turn].filter(Boolean).join(`
22595
+ `) : turn;
22574
22596
  return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
22575
22597
  }
22576
22598
  case "shell.pre": {
@@ -23379,6 +23401,7 @@ var codexAdapter = {
23379
23401
  },
23380
23402
  permissionMode: input.permission_mode,
23381
23403
  transcriptPath: input.transcript_path,
23404
+ model: input.model,
23382
23405
  event: protocolEvent(input)
23383
23406
  }
23384
23407
  };
@@ -79,6 +79,6 @@ if (quiet)
79
79
  process.stdout.write(`${JSON.stringify({ hookSpecificOutput: { hookEventName: quiet } })}
80
80
  `);
81
81
  else {
82
- const { runCodexHook } = await import("./workit-hook-pmdzgzzk.js");
82
+ const { runCodexHook } = await import("./workit-hook-kcvskw9d.js");
83
83
  await runCodexHook([payload]);
84
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-codex",
3
- "version": "8.32.0",
3
+ "version": "8.33.0",
4
4
  "private": false,
5
5
  "description": "Workit Codex CLI/desktop plugin — shared MCP transport, hooks, method skills, and verifier/reviewer/implementer agents",
6
6
  "keywords": [
@@ -39,8 +39,8 @@
39
39
  "build": "bun scripts/build.ts"
40
40
  },
41
41
  "devDependencies": {
42
- "@brainervirus/workit-core": "^8.32.0",
43
- "@brainervirus/workit-mcp": "^8.32.0"
42
+ "@brainervirus/workit-core": "^8.33.0",
43
+ "@brainervirus/workit-mcp": "^8.33.0"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=24"