@darkhunt-security/endpoint-codex 0.9.14 → 0.9.15

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": "darkhunt-guard",
3
- "version": "0.9.14",
3
+ "version": "0.9.15",
4
4
  "hooks": "./hooks/hooks.json",
5
5
  "description": "Darkhunt endpoint plugin for Codex CLI \u2014 full session trace capture and PreToolUse guardrails.",
6
6
  "author": {
@@ -18880,6 +18880,19 @@ function isAlive(pid) {
18880
18880
  return false;
18881
18881
  }
18882
18882
  }
18883
+ var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
18884
+ async function acquireLockWithin(scope, timeoutMs, sleep2 = (ms) => new Promise((r) => setTimeout(r, ms)), now = Date.now) {
18885
+ const deadline = now() + timeoutMs;
18886
+ for (; ; ) {
18887
+ const release = acquireLock(scope);
18888
+ if (release)
18889
+ return release;
18890
+ const remaining = deadline - now();
18891
+ if (remaining <= 0)
18892
+ return null;
18893
+ await sleep2(Math.min(250, remaining));
18894
+ }
18895
+ }
18883
18896
 
18884
18897
  // packages/core/dist/forwarder/export-status.js
18885
18898
  init_esm();
@@ -21711,7 +21724,9 @@ function tryLoadConfig(vendor, options) {
21711
21724
  }
21712
21725
  async function runForwarder(mapper, options = {}) {
21713
21726
  const config = options.config ?? tryLoadConfig(mapper.vendor, options);
21714
- const release = acquireLock(config?.scope ?? mapper.vendor);
21727
+ const scope = config?.scope ?? mapper.vendor;
21728
+ const waited = options.lockWaitMs !== void 0 && options.lockWaitMs > 0;
21729
+ const release = waited ? await acquireLockWithin(scope, options.lockWaitMs) : acquireLock(scope);
21715
21730
  if (!release) {
21716
21731
  return {
21717
21732
  transcripts: 0,
@@ -21720,7 +21735,12 @@ async function runForwarder(mapper, options = {}) {
21720
21735
  kinds: {},
21721
21736
  warnings: [],
21722
21737
  emitted: { transcripts: 0, records: 0 },
21723
- ok: true
21738
+ lockBusy: true,
21739
+ // A caller that waited and still did not get it has had its request dropped, and
21740
+ // must not exit zero on it. One that never asked to wait was simply beaten to
21741
+ // work that is now someone else's, which is success.
21742
+ ok: !waited,
21743
+ ...waited ? { error: "another forwarder holds the lock" } : {}
21724
21744
  };
21725
21745
  }
21726
21746
  const result2 = {
@@ -22053,6 +22073,10 @@ async function runBackfill(mapper, options, say2) {
22053
22073
  const pass = (subset) => runForwarder(mapper, {
22054
22074
  paths: subset,
22055
22075
  dryRun: options.dryRun,
22076
+ // A backfill is an instruction, not an opportunistic spawn: it waits for the lock
22077
+ // that a hook-fired forwarder may hold, and treats never getting it as a failure
22078
+ // rather than reporting the `shipped 0` an up-to-date machine also prints.
22079
+ ...options.dryRun ? {} : { lockWaitMs: options.lockWaitMs ?? DEFAULT_LOCK_WAIT_MS },
22056
22080
  ...options.profile !== void 0 ? { profile: options.profile } : {},
22057
22081
  ...options.credentialsPath !== void 0 ? { credentialsPath: options.credentialsPath } : {}
22058
22082
  });
@@ -22087,7 +22111,9 @@ async function runPasses(groups, pass, say2) {
22087
22111
  total.ok = false;
22088
22112
  if (result2.error !== void 0)
22089
22113
  total.error = result2.error;
22090
- say2(`stopped in batch ${index + 1} of ${groups.length}; earlier batches are checkpointed`);
22114
+ if (result2.lockBusy === true)
22115
+ total.lockBusy = true;
22116
+ say2(result2.lockBusy === true ? `batch ${index + 1} of ${groups.length} could not start: another forwarder holds the lock` : `stopped in batch ${index + 1} of ${groups.length}; earlier batches are checkpointed`);
22091
22117
  break;
22092
22118
  }
22093
22119
  if (groups.length > 1) {
@@ -22498,6 +22524,11 @@ for (const [kind, n] of Object.entries(result.kinds).sort((a, b) => b[1] - a[1])
22498
22524
  for (const skip of result.skipped) say(`skipped ${skip}`);
22499
22525
  for (const warning of result.warnings ?? []) say(`WARNING ${warning}`);
22500
22526
  if (result.ok === false) {
22527
+ if (result.lockBusy === true) {
22528
+ say("NOT RUN \u2014 another forwarder held the lock for the whole wait");
22529
+ say("nothing was shipped; re-run when the capture lane is idle");
22530
+ process.exit(3);
22531
+ }
22501
22532
  say(`EXPORT FAILED \u2014 ${result.error}`);
22502
22533
  if (result.emitted.records > 0) {
22503
22534
  say(
@@ -66,6 +66,7 @@ var LINE_CEILING = 64 * 1024 * 1024;
66
66
 
67
67
  // packages/core/dist/forwarder/lock.js
68
68
  var STALE_MS = 5 * 60 * 1e3;
69
+ var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
69
70
 
70
71
  // node_modules/@darkhunt-security/telemetry/package.json
71
72
  var package_default = {
@@ -18880,6 +18880,19 @@ function isAlive(pid) {
18880
18880
  return false;
18881
18881
  }
18882
18882
  }
18883
+ var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
18884
+ async function acquireLockWithin(scope, timeoutMs, sleep2 = (ms) => new Promise((r) => setTimeout(r, ms)), now = Date.now) {
18885
+ const deadline = now() + timeoutMs;
18886
+ for (; ; ) {
18887
+ const release = acquireLock(scope);
18888
+ if (release)
18889
+ return release;
18890
+ const remaining = deadline - now();
18891
+ if (remaining <= 0)
18892
+ return null;
18893
+ await sleep2(Math.min(250, remaining));
18894
+ }
18895
+ }
18883
18896
 
18884
18897
  // packages/core/dist/forwarder/export-status.js
18885
18898
  init_esm();
@@ -21711,7 +21724,9 @@ function tryLoadConfig(vendor, options) {
21711
21724
  }
21712
21725
  async function runForwarder(mapper, options = {}) {
21713
21726
  const config = options.config ?? tryLoadConfig(mapper.vendor, options);
21714
- const release = acquireLock(config?.scope ?? mapper.vendor);
21727
+ const scope = config?.scope ?? mapper.vendor;
21728
+ const waited = options.lockWaitMs !== void 0 && options.lockWaitMs > 0;
21729
+ const release = waited ? await acquireLockWithin(scope, options.lockWaitMs) : acquireLock(scope);
21715
21730
  if (!release) {
21716
21731
  return {
21717
21732
  transcripts: 0,
@@ -21720,7 +21735,12 @@ async function runForwarder(mapper, options = {}) {
21720
21735
  kinds: {},
21721
21736
  warnings: [],
21722
21737
  emitted: { transcripts: 0, records: 0 },
21723
- ok: true
21738
+ lockBusy: true,
21739
+ // A caller that waited and still did not get it has had its request dropped, and
21740
+ // must not exit zero on it. One that never asked to wait was simply beaten to
21741
+ // work that is now someone else's, which is success.
21742
+ ok: !waited,
21743
+ ...waited ? { error: "another forwarder holds the lock" } : {}
21724
21744
  };
21725
21745
  }
21726
21746
  const result = {
@@ -399,6 +399,7 @@ var LINE_CEILING = 64 * 1024 * 1024;
399
399
 
400
400
  // packages/core/dist/forwarder/lock.js
401
401
  var STALE_MS = 5 * 60 * 1e3;
402
+ var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
402
403
 
403
404
  // node_modules/@darkhunt-security/telemetry/package.json
404
405
  var package_default = {
package/dist/bin/init.mjs CHANGED
@@ -58,6 +58,7 @@ var LINE_CEILING = 64 * 1024 * 1024;
58
58
 
59
59
  // packages/core/dist/forwarder/lock.js
60
60
  var STALE_MS = 5 * 60 * 1e3;
61
+ var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
61
62
 
62
63
  // node_modules/@darkhunt-security/telemetry/package.json
63
64
  var package_default = {
@@ -201,6 +201,7 @@ var LINE_CEILING = 64 * 1024 * 1024;
201
201
 
202
202
  // packages/core/dist/forwarder/lock.js
203
203
  var STALE_MS = 5 * 60 * 1e3;
204
+ var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
204
205
 
205
206
  // node_modules/@darkhunt-security/telemetry/package.json
206
207
  var package_default = {
@@ -190,6 +190,7 @@ var LINE_CEILING = 64 * 1024 * 1024;
190
190
 
191
191
  // packages/core/dist/forwarder/lock.js
192
192
  var STALE_MS = 5 * 60 * 1e3;
193
+ var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
193
194
 
194
195
  // packages/core/dist/forwarder/health.js
195
196
  import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkhunt-security/endpoint-codex",
3
- "version": "0.9.14",
3
+ "version": "0.9.15",
4
4
  "type": "module",
5
5
  "description": "Darkhunt endpoint adapter for Codex CLI: hook codec, rollout transcript mapper, plugin manifest.",
6
6
  "bin": {