@brainervirus/workit-claude-code 8.27.0 → 8.28.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,7 +1,7 @@
1
1
  {
2
2
  "name": "workit",
3
3
  "displayName": "Workit",
4
- "version": "8.27.0",
4
+ "version": "8.28.0",
5
5
  "description": "Workflow rails for agentic coding: task context on every session, branch policy on shell commands, and the workit method skills",
6
6
  "author": {
7
7
  "name": "BrainerVirus"
@@ -213,10 +213,51 @@ const standingPending = (cwd, session, agentId) => {
213
213
  return readJson(path.join(store, "standing", "seen", `${key}.json`))?.rev !== rev;
214
214
  };
215
215
 
216
+ // The plugin dir this hook runs from (`<config>/plugins/cache/<mkt>/workit/<version>`)
217
+ // against the newest version the registry lists beside it: while the line has not
218
+ // been given this session, the runtime runs (src/stale-plugin.ts holds the same test).
219
+ const parts = (version) => /^(\d+)\.(\d+)\.(\d+)/.exec(version)?.slice(1).map(Number);
220
+ const staleUnannounced = (session) => {
221
+ try {
222
+ const versions = path.dirname(root);
223
+ if (path.basename(path.dirname(path.dirname(versions))) !== "cache") return false;
224
+ const running = parts(path.basename(root));
225
+ if (!running || typeof session !== "string") return false;
226
+ const registry = readJson(
227
+ path.join(path.dirname(path.dirname(path.dirname(versions))), "installed_plugins.json"),
228
+ );
229
+ for (const entries of Object.values(registry?.plugins ?? {}))
230
+ for (const entry of Array.isArray(entries) ? entries : []) {
231
+ const at = typeof entry?.version === "string" ? parts(entry.version) : undefined;
232
+ if (
233
+ at &&
234
+ path.dirname(String(entry.installPath)) === versions &&
235
+ (at[0] - running[0] || at[1] - running[1] || at[2] - running[2]) > 0
236
+ )
237
+ return !existsSync(markerFor(session, entry.version));
238
+ }
239
+ } catch {
240
+ // an unreadable registry is not a reason to load the runtime
241
+ }
242
+ return false;
243
+ };
244
+ const markerFor = (session, installed) =>
245
+ path.join(
246
+ stateDir(),
247
+ "stale-plugin",
248
+ createHash("sha256").update(`${session}\0${installed}`).digest("hex").slice(0, 32),
249
+ );
250
+
216
251
  const fastAllow = (() => {
217
252
  try {
218
253
  const value = JSON.parse(payload);
219
254
  const command = value?.tool_input?.command;
255
+ if (
256
+ value?.hook_event_name === "PreToolUse" &&
257
+ !value.agent_id &&
258
+ staleUnannounced(value.session_id)
259
+ )
260
+ return false;
220
261
  if (value?.hook_event_name === "PostToolUse")
221
262
  return typeof command === "string" && !/\bcommit\b/.test(command);
222
263
  if (value?.hook_event_name !== "PreToolUse") return false;
@@ -233,12 +274,16 @@ const fastAllow = (() => {
233
274
  return true;
234
275
  return !implementer && !RAW_TOOLS.test(command) && !hasTaskStore(String(value.cwd ?? "."));
235
276
  }
277
+ // A subagent spawn that names its model has no default to fill (hooks/agent-model.ts).
278
+ if (value.tool_name === "Agent" || value.tool_name === "Task")
279
+ return typeof value.tool_input?.model === "string" && value.tool_input.model.trim() !== "";
236
280
  return EDITS.has(value.tool_name) && !implementer && !hasTaskStore(String(value.cwd ?? "."));
237
281
  } catch {
238
282
  return false;
239
283
  }
240
284
  })();
241
285
 
286
+ process.env.WORKIT_PLUGIN_ROOT = root;
242
287
  if (fastAllow) {
243
288
  process.stdout.write("{}\n");
244
289
  } else if (fromSource) {