@brainervirus/workit-codex 8.32.0 → 8.34.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.34.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
  }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ recordHookRun2
4
+ } from "./workit-hook-w6s3hcyz.js";
5
+ import"./workit-hook-eaahdgen.js";
6
+ export {
7
+ recordHookRun2 as recordHookRun
8
+ };
@@ -15,6 +15,9 @@ import {
15
15
  checkCommand,
16
16
  maybeHeavy2
17
17
  } from "./workit-hook-eaahdgen.js";
18
+ import {
19
+ recordHookRun2
20
+ } from "./workit-hook-w6s3hcyz.js";
18
21
  // packages/workit-core/src/hooks/descriptor.ts
19
22
  var support = (descriptor, axis) => {
20
23
  if (axis.startsWith("event:"))
@@ -17628,7 +17631,14 @@ var sessionMarkerFile = (input, session, store) => {
17628
17631
  return path19.join(dir, "hooks", `skills-${name}.json`);
17629
17632
  };
17630
17633
  var list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
17631
- var EMPTY = { nudged: [], loaded: [], raw: [], stops: [], judges: [] };
17634
+ var EMPTY = {
17635
+ nudged: [],
17636
+ loaded: [],
17637
+ raw: [],
17638
+ stops: [],
17639
+ judges: [],
17640
+ model: null
17641
+ };
17632
17642
  var readRaw = (file) => {
17633
17643
  try {
17634
17644
  return fs14.readFileSync(file, "utf8");
@@ -17644,7 +17654,8 @@ var parseMarker = (text) => {
17644
17654
  loaded: list2(value.loaded),
17645
17655
  raw: list2(value.raw),
17646
17656
  stops: list2(value.stops),
17647
- judges: list2(value.judges)
17657
+ judges: list2(value.judges),
17658
+ model: typeof value.model === "string" ? value.model : null
17648
17659
  };
17649
17660
  } catch {
17650
17661
  return { ...EMPTY };
@@ -17689,6 +17700,18 @@ var trackJudge = (input, agentId, running) => {
17689
17700
  return { ...marker, judges: running ? [...rest, agentId] : rest };
17690
17701
  });
17691
17702
  };
17703
+ var modelSwitchedOnDisk = (input) => {
17704
+ const session = input.session.id;
17705
+ const model = input.model;
17706
+ const file = session && model ? sessionMarkerFile(input, session) : null;
17707
+ if (!file || !model)
17708
+ return false;
17709
+ const previous = readSessionMarker(file).model;
17710
+ if (previous === model)
17711
+ return false;
17712
+ updateSessionMarker(file, (marker) => ({ ...marker, model }));
17713
+ return previous !== null;
17714
+ };
17692
17715
 
17693
17716
  // packages/workit-core/src/hooks/shell-words.ts
17694
17717
  class ShellAnalysisError extends Error {
@@ -22570,7 +22593,9 @@ function decide(input, deps) {
22570
22593
  if (!usable2(descriptor.context.perTurn))
22571
22594
  return NONE6;
22572
22595
  const current = turnContextText(input, descriptor);
22573
- const text = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
22596
+ const turn = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
22597
+ const text = input.model && modelSwitchedOnDisk(input) ? [invariantBootstrap(), turn].filter(Boolean).join(`
22598
+ `) : turn;
22574
22599
  return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
22575
22600
  }
22576
22601
  case "shell.pre": {
@@ -23379,6 +23404,7 @@ var codexAdapter = {
23379
23404
  },
23380
23405
  permissionMode: input.permission_mode,
23381
23406
  transcriptPath: input.transcript_path,
23407
+ model: input.model,
23382
23408
  event: protocolEvent(input)
23383
23409
  }
23384
23410
  };
@@ -23707,6 +23733,8 @@ async function runHookProcess(host, stdin, stdout, stderr = process.stderr, env
23707
23733
  } catch {
23708
23734
  raw = undefined;
23709
23735
  }
23736
+ const native = raw?.hook_event_name;
23737
+ recordHookRun2(typeof host === "string" ? host : adapter.descriptor.host, typeof native === "string" ? native : null, env);
23710
23738
  const result = text === null ? skippedHook(adapter, undefined, env, budget, "input") : await dispatchWithin(adapter, raw, env, budget, deadline.dispatch);
23711
23739
  if (result.skipped)
23712
23740
  stderr.write(`[workit] ${result.error}
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ stateDir2
4
+ } from "./workit-hook-eaahdgen.js";
5
+
6
+ // packages/workit-core/src/hooks/hook-runs.ts
7
+ import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
8
+ import path from "node:path";
9
+ var HOOK_RUNS_DIR = "hook-runs";
10
+ var safe = (part) => part.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 64);
11
+ var runFile = (dir, host, event) => path.join(dir, HOOK_RUNS_DIR, `${safe(host)}__${safe(event)}.json`);
12
+ var recordHookRun2 = (host, event, env = process.env, now = Date.now) => {
13
+ if (!event)
14
+ return;
15
+ try {
16
+ const dir = stateDir2(env);
17
+ const file = runFile(dir, host, event);
18
+ let count = 0;
19
+ try {
20
+ const previous = JSON.parse(readFileSync(file, "utf8"));
21
+ if (typeof previous.count === "number" && Number.isFinite(previous.count))
22
+ count = previous.count;
23
+ } catch {}
24
+ const row = {
25
+ host,
26
+ event,
27
+ at: new Date(now()).toISOString(),
28
+ count: count + 1
29
+ };
30
+ try {
31
+ writeFileSync(file, JSON.stringify(row));
32
+ } catch {
33
+ mkdirSync(path.dirname(file), { recursive: true });
34
+ writeFileSync(file, JSON.stringify(row));
35
+ }
36
+ } catch {}
37
+ };
38
+ export { recordHookRun2 };
@@ -36,6 +36,7 @@ if (tooOld) {
36
36
  }
37
37
  var { maybeHeavy, stateDir } = await import("./workit-hook-9pq84bdw.js");
38
38
  var { standingPending } = await import("./workit-hook-mk64s4fk.js");
39
+ var { recordHookRun } = await import("./workit-hook-b9ansxvm.js");
39
40
  var payload = "";
40
41
  for await (const chunk of process.stdin)
41
42
  payload += String(chunk);
@@ -75,10 +76,12 @@ var quietEvent = () => {
75
76
  }
76
77
  };
77
78
  var quiet = quietEvent();
78
- if (quiet)
79
+ if (quiet) {
80
+ if (quiet === "PreToolUse")
81
+ recordHookRun(process.env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || process.env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli", quiet);
79
82
  process.stdout.write(`${JSON.stringify({ hookSpecificOutput: { hookEventName: quiet } })}
80
83
  `);
81
- else {
82
- const { runCodexHook } = await import("./workit-hook-pmdzgzzk.js");
84
+ } else {
85
+ const { runCodexHook } = await import("./workit-hook-h4ryf1zq.js");
83
86
  await runCodexHook([payload]);
84
87
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-codex",
3
- "version": "8.32.0",
3
+ "version": "8.34.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.34.0",
43
+ "@brainervirus/workit-mcp": "^8.34.0"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=24"