@brainervirus/workit-codex 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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workit",
3
- "version": "8.31.1",
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 = [];
@@ -14950,6 +14951,7 @@ var workspaceConfigSchema = object({
14950
14951
  verification: _enum(["proportional", "self", "independent"]).optional(),
14951
14952
  delegation: unknown().optional(),
14952
14953
  trailers: boolean2().optional(),
14954
+ deleteBranch: boolean2().optional(),
14953
14955
  liveSessionGuard: boolean2().optional(),
14954
14956
  fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
14955
14957
  models: object({ roles: unknown().optional() }).passthrough().optional(),
@@ -27769,6 +27771,40 @@ class StdioServerTransport {
27769
27771
 
27770
27772
  // packages/workit-mcp/src/server.ts
27771
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
27772
27808
  class McpCapabilityUnavailableError extends Error {
27773
27809
  capability;
27774
27810
  constructor(capability) {
@@ -27863,8 +27899,8 @@ var sanitizeFailure = (result, workspaceRoot) => {
27863
27899
  };
27864
27900
  return sanitize(result);
27865
27901
  };
27866
- var resultForClient = (result, workspaceRoot) => {
27867
- const safe = sanitizeFailure(result, workspaceRoot);
27902
+ var resultForClient = (result, workspaceRoot, escalate = (safe) => safe) => {
27903
+ const safe = escalate(sanitizeFailure(result, workspaceRoot));
27868
27904
  return {
27869
27905
  content: [{ type: "text", text: JSON.stringify(safe) }],
27870
27906
  structuredContent: safe,
@@ -27901,6 +27937,7 @@ function createMcpServer(host, contextProvider) {
27901
27937
  path23.join(here, "..", "..", "workit-core", "src", "core", "task-engine.ts")
27902
27938
  ].filter((file) => existsSync9(file)));
27903
27939
  let staleWarned = false;
27940
+ const failures = new Map;
27904
27941
  const server = new Server({ name: "workit", version: VERSION }, { capabilities: { tools: {}, resources: {} } });
27905
27942
  server.setRequestHandler(ListToolsRequestSchema, async () => {
27906
27943
  let attested = false;
@@ -28023,9 +28060,10 @@ function createMcpServer(host, contextProvider) {
28023
28060
  details: { operation: family }
28024
28061
  }, workspaceRoot);
28025
28062
  }
28063
+ const escalate = (safe) => escalateToolFailure(failures, context.caller.actor || "mcp", toolName, request.params.arguments, safe);
28026
28064
  const parsed = parseAdvertisedOperation(family, request.params.arguments, host);
28027
28065
  if (!parsed.ok)
28028
- return resultForClient(parsed, workspaceRoot);
28066
+ return resultForClient(parsed, workspaceRoot, escalate);
28029
28067
  if (context.callerAttested !== true && requiresCallerIdentity(parsed.data))
28030
28068
  return resultForClient({
28031
28069
  ok: false,
@@ -28037,7 +28075,7 @@ function createMcpServer(host, contextProvider) {
28037
28075
  const core = new WorkitCore(new TaskStore(context.root), context);
28038
28076
  const run = core[family];
28039
28077
  const result = run.call(core, parsed.data);
28040
- 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);
28041
28079
  } catch (error) {
28042
28080
  return thrownResult(toolName, error, workspaceRoot);
28043
28081
  }
@@ -6283,6 +6283,7 @@ var workspaceConfigSchema = object({
6283
6283
  verification: _enum(["proportional", "self", "independent"]).optional(),
6284
6284
  delegation: unknown().optional(),
6285
6285
  trailers: boolean2().optional(),
6286
+ deleteBranch: boolean2().optional(),
6286
6287
  liveSessionGuard: boolean2().optional(),
6287
6288
  fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
6288
6289
  models: object({ roles: unknown().optional() }).passthrough().optional(),
@@ -17627,7 +17628,14 @@ var sessionMarkerFile = (input, session, store) => {
17627
17628
  return path19.join(dir, "hooks", `skills-${name}.json`);
17628
17629
  };
17629
17630
  var list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
17630
- var EMPTY = { nudged: [], loaded: [], raw: [], stops: [], judges: [] };
17631
+ var EMPTY = {
17632
+ nudged: [],
17633
+ loaded: [],
17634
+ raw: [],
17635
+ stops: [],
17636
+ judges: [],
17637
+ model: null
17638
+ };
17631
17639
  var readRaw = (file) => {
17632
17640
  try {
17633
17641
  return fs14.readFileSync(file, "utf8");
@@ -17643,7 +17651,8 @@ var parseMarker = (text) => {
17643
17651
  loaded: list2(value.loaded),
17644
17652
  raw: list2(value.raw),
17645
17653
  stops: list2(value.stops),
17646
- judges: list2(value.judges)
17654
+ judges: list2(value.judges),
17655
+ model: typeof value.model === "string" ? value.model : null
17647
17656
  };
17648
17657
  } catch {
17649
17658
  return { ...EMPTY };
@@ -17688,6 +17697,18 @@ var trackJudge = (input, agentId, running) => {
17688
17697
  return { ...marker, judges: running ? [...rest, agentId] : rest };
17689
17698
  });
17690
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
+ };
17691
17712
 
17692
17713
  // packages/workit-core/src/hooks/shell-words.ts
17693
17714
  class ShellAnalysisError extends Error {
@@ -22569,7 +22590,9 @@ function decide(input, deps) {
22569
22590
  if (!usable2(descriptor.context.perTurn))
22570
22591
  return NONE6;
22571
22592
  const current = turnContextText(input, descriptor);
22572
- 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;
22573
22596
  return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
22574
22597
  }
22575
22598
  case "shell.pre": {
@@ -23378,6 +23401,7 @@ var codexAdapter = {
23378
23401
  },
23379
23402
  permissionMode: input.permission_mode,
23380
23403
  transcriptPath: input.transcript_path,
23404
+ model: input.model,
23381
23405
  event: protocolEvent(input)
23382
23406
  }
23383
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-9tnjrhr5.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.31.1",
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.31.1",
43
- "@brainervirus/workit-mcp": "^8.31.1"
42
+ "@brainervirus/workit-core": "^8.33.0",
43
+ "@brainervirus/workit-mcp": "^8.33.0"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=24"