@darkhunt-security/endpoint-codex 0.9.16 → 0.9.18

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.
@@ -3,8 +3,8 @@ import { createRequire as __dhCreateRequire } from 'node:module';
3
3
  const require = __dhCreateRequire(import.meta.url);
4
4
 
5
5
  // adapters/codex/bin/status.mjs
6
- import { readFileSync as readFileSync8 } from "node:fs";
7
- import { dirname, join as join12 } from "node:path";
6
+ import { readFileSync as readFileSync9 } from "node:fs";
7
+ import { dirname, join as join13 } from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
9
 
10
10
  // packages/core/dist/config/local.js
@@ -87,6 +87,9 @@ function settingsFor(file, vendor) {
87
87
  ...file.enforce ?? override.enforce ? { enforce: { ...file.enforce, ...override.enforce } } : {}
88
88
  };
89
89
  }
90
+ function resolveCapture(capture) {
91
+ return { enabled: capture?.enabled ?? true, backfill: capture?.backfill ?? false };
92
+ }
90
93
  function readConfigFile(vendor) {
91
94
  if (!existsSync(configPath())) {
92
95
  throw new ConfigMissingError(`${configPath()} does not exist \u2014 run init.mjs to create it`);
@@ -139,7 +142,7 @@ function loadLocalConfig(vendor, options = {}) {
139
142
  applicationId,
140
143
  ...(creds.userId ?? vendorFile.userId) !== void 0 ? { userId: creds.userId ?? vendorFile.userId } : {},
141
144
  enabled: vendorFile.enabled ?? true,
142
- capture: { enabled: vendorFile.capture?.enabled ?? true },
145
+ capture: resolveCapture(vendorFile.capture),
143
146
  enforce: {
144
147
  mode: vendorFile.enforce?.mode ?? "off",
145
148
  failClosed: vendorFile.enforce?.failClosed ?? true
@@ -170,8 +173,11 @@ function loadBeat(scope) {
170
173
  }
171
174
  }
172
175
 
176
+ // packages/core/dist/emit/emitter.js
177
+ var PAYLOAD_LIMIT = 128 * 1024;
178
+
173
179
  // packages/core/dist/forwarder/checkpoint.js
174
- import { mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3, renameSync as renameSync2, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
180
+ import { copyFileSync, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3, renameSync as renameSync2, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
175
181
  import { join as join6 } from "node:path";
176
182
  function checkpointPath(scope) {
177
183
  return join6(CONFIG_DIR, `${scope}.checkpoints.json`);
@@ -190,6 +196,7 @@ var LINE_CEILING = 64 * 1024 * 1024;
190
196
 
191
197
  // packages/core/dist/forwarder/lock.js
192
198
  var STALE_MS = 5 * 60 * 1e3;
199
+ var HEARTBEAT_MS = 60 * 1e3;
193
200
  var DEFAULT_LOCK_WAIT_MS = 60 * 1e3;
194
201
 
195
202
  // packages/core/dist/forwarder/health.js
@@ -206,6 +213,35 @@ function loadHealth(scope) {
206
213
  }
207
214
  }
208
215
 
216
+ // packages/core/dist/forwarder/pending.js
217
+ import { existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync5, renameSync as renameSync4, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
218
+ import { join as join8 } from "node:path";
219
+ function pendingPath(scope) {
220
+ return join8(CONFIG_DIR, `${scope}.pending.json`);
221
+ }
222
+ function loadPending(scope) {
223
+ try {
224
+ const backlog = JSON.parse(readFileSync5(pendingPath(scope), "utf8"));
225
+ if (!Array.isArray(backlog.paths))
226
+ return void 0;
227
+ return backlog;
228
+ } catch {
229
+ return void 0;
230
+ }
231
+ }
232
+ function pendingTranscripts(scope) {
233
+ const backlog = loadPending(scope);
234
+ if (!backlog)
235
+ return [];
236
+ return backlog.paths.filter((path) => {
237
+ try {
238
+ return existsSync2(path);
239
+ } catch {
240
+ return false;
241
+ }
242
+ });
243
+ }
244
+
209
245
  // node_modules/@darkhunt-security/telemetry/package.json
210
246
  var package_default = {
211
247
  name: "@darkhunt-security/telemetry",
@@ -1132,9 +1168,12 @@ var VALIDATORS = Object.freeze({
1132
1168
  // node_modules/@darkhunt-security/telemetry/dist/client.js
1133
1169
  var LIB_VERSION = package_default.version;
1134
1170
 
1171
+ // packages/core/dist/forwarder/retry.js
1172
+ var CLAIM_STALE_MS = 45 * 60 * 1e3;
1173
+
1135
1174
  // packages/core/dist/cli/status.js
1136
- import { existsSync as existsSync2, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
1137
- import { join as join8 } from "node:path";
1175
+ import { existsSync as existsSync3, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
1176
+ import { join as join9 } from "node:path";
1138
1177
  var SESSION_HOOK_STALE_MS = 30 * 60 * 1e3;
1139
1178
  function countSubagents(mapper, checkpoints) {
1140
1179
  if (!mapper?.subagentOf || !mapper.sessionRoots)
@@ -1149,7 +1188,7 @@ function countSubagents(mapper, checkpoints) {
1149
1188
  return;
1150
1189
  }
1151
1190
  for (const entry of entries) {
1152
- const full = join8(dir, entry.name);
1191
+ const full = join9(dir, entry.name);
1153
1192
  if (entry.isDirectory()) {
1154
1193
  walk(full);
1155
1194
  continue;
@@ -1174,16 +1213,19 @@ function status(vendor, mapper) {
1174
1213
  for (const [path, cp] of Object.entries(checkpoints)) {
1175
1214
  if (path === "::spool::")
1176
1215
  continue;
1177
- const size = existsSync2(path) ? statSync3(path).size : 0;
1216
+ const size = existsSync3(path) ? statSync3(path).size : 0;
1178
1217
  transcripts.push({ path, shipped: cp.offset, size, lag: Math.max(0, size - cp.offset) });
1179
1218
  }
1180
1219
  const subagents = countSubagents(mapper, checkpoints);
1181
1220
  const lastPass = loadHealth(config.scope);
1221
+ const backlog = loadPending(config.scope);
1222
+ const heldTranscripts = pendingTranscripts(config.scope).length;
1223
+ const pending = backlog && heldTranscripts > 0 ? { transcripts: heldTranscripts, since: backlog.since, at: backlog.at } : void 0;
1182
1224
  const spool = spoolPath(vendor);
1183
1225
  let spoolEvents = 0;
1184
1226
  let spoolLastAt;
1185
- if (existsSync2(spool)) {
1186
- const lines = readFileSync5(spool, "utf8").split("\n").filter(Boolean);
1227
+ if (existsSync3(spool)) {
1228
+ const lines = readFileSync6(spool, "utf8").split("\n").filter(Boolean);
1187
1229
  spoolEvents = lines.length;
1188
1230
  const last = lines[lines.length - 1];
1189
1231
  if (last) {
@@ -1208,6 +1250,9 @@ function status(vendor, mapper) {
1208
1250
  workspaceId: config.workspaceId,
1209
1251
  scope: config.scope,
1210
1252
  capture: config.capture.enabled && config.enabled,
1253
+ // Each switch above it can also stop an import, so all three have to agree before
1254
+ // this may claim a backfill would run.
1255
+ backfill: config.capture.backfill && config.capture.enabled && config.enabled,
1211
1256
  enforce: config.enabled ? config.enforce.mode : "off (kill switch)",
1212
1257
  spoolEvents,
1213
1258
  ...spoolLastAt !== void 0 ? { spoolLastAt } : {},
@@ -1218,19 +1263,20 @@ function status(vendor, mapper) {
1218
1263
  transcripts,
1219
1264
  totalLag: transcripts.reduce((sum, t) => sum + t.lag, 0),
1220
1265
  ...lastPass !== void 0 ? { lastPass } : {},
1266
+ ...pending !== void 0 ? { pending } : {},
1221
1267
  ...subagents !== void 0 ? { subagents } : {},
1222
- lockHeld: existsSync2(spool.replace(/spool\/.*$/, `${config.scope}.forwarder.lock`))
1268
+ lockHeld: existsSync3(spool.replace(/spool\/.*$/, `${config.scope}.forwarder.lock`))
1223
1269
  };
1224
1270
  }
1225
1271
 
1226
1272
  // packages/core/dist/cli/enroll.js
1227
1273
  import { homedir as homedir3 } from "node:os";
1228
- import { join as join9 } from "node:path";
1229
- var CLI_CREDENTIALS_PATH = join9(homedir3(), ".darkhunt", "credentials.json");
1274
+ import { join as join10 } from "node:path";
1275
+ var CLI_CREDENTIALS_PATH = join10(homedir3(), ".darkhunt", "credentials.json");
1230
1276
 
1231
1277
  // adapters/codex/dist/transcript.js
1232
- import { readFileSync as readFileSync6 } from "node:fs";
1233
- import { basename, join as join10 } from "node:path";
1278
+ import { readFileSync as readFileSync7 } from "node:fs";
1279
+ import { basename, join as join11 } from "node:path";
1234
1280
  import { homedir as homedir4 } from "node:os";
1235
1281
  function str(value) {
1236
1282
  return typeof value === "string" ? value : void 0;
@@ -1374,7 +1420,7 @@ function stripSuffix(path) {
1374
1420
  var codexTranscript = {
1375
1421
  vendor: "codex",
1376
1422
  sessionRoots() {
1377
- return [join10(homedir4(), ".codex", "sessions")];
1423
+ return [join11(homedir4(), ".codex", "sessions")];
1378
1424
  },
1379
1425
  /**
1380
1426
  * `~/.codex/auth.json` -> the `email` claim of `tokens.id_token`.
@@ -1396,7 +1442,7 @@ var codexTranscript = {
1396
1442
  */
1397
1443
  resolveUserId() {
1398
1444
  try {
1399
- return emailFromAuth(readFileSync6(join10(homedir4(), ".codex", "auth.json"), "utf8"));
1445
+ return emailFromAuth(readFileSync7(join11(homedir4(), ".codex", "auth.json"), "utf8"));
1400
1446
  } catch {
1401
1447
  return void 0;
1402
1448
  }
@@ -1607,14 +1653,14 @@ var codexTranscript = {
1607
1653
  };
1608
1654
 
1609
1655
  // adapters/codex/bin/lib/launchers.mjs
1610
- import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "node:fs";
1656
+ import { chmodSync, existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "node:fs";
1611
1657
  import { homedir as homedir5 } from "node:os";
1612
- import { join as join11 } from "node:path";
1658
+ import { join as join12 } from "node:path";
1613
1659
  var LAUNCHERS = {
1614
1660
  "darkhunt-codex-spool": "spool.mjs",
1615
1661
  "darkhunt-codex-guard": "guard.mjs"
1616
1662
  };
1617
- var BIN_DIR = join11(homedir5(), ".local", "bin");
1663
+ var BIN_DIR = join12(homedir5(), ".local", "bin");
1618
1664
  var script = (target) => `#!/bin/sh
1619
1665
  # Installed by darkhunt endpoint-plugins. Resolves the newest installed
1620
1666
  # plugin version at run time; do not hard-code a version here.
@@ -1626,14 +1672,14 @@ function launcherState(binDir = BIN_DIR, path = process.env["PATH"] ?? "") {
1626
1672
  const missing = [];
1627
1673
  const stale = [];
1628
1674
  for (const [name, target] of Object.entries(LAUNCHERS)) {
1629
- const file = join11(binDir, name);
1630
- if (!existsSync3(file)) {
1675
+ const file = join12(binDir, name);
1676
+ if (!existsSync4(file)) {
1631
1677
  missing.push(name);
1632
1678
  continue;
1633
1679
  }
1634
1680
  let body = "";
1635
1681
  try {
1636
- body = readFileSync7(file, "utf8");
1682
+ body = readFileSync8(file, "utf8");
1637
1683
  } catch {
1638
1684
  }
1639
1685
  if (body !== script(target)) stale.push(name);
@@ -1668,10 +1714,10 @@ try {
1668
1714
  const s = status("codex", codexTranscript);
1669
1715
  const n = (x) => x.toLocaleString();
1670
1716
  console.log(`darkhunt endpoint status \u2014 codex`);
1671
- const root = join12(dirname(fileURLToPath(import.meta.url)), "..", "..");
1717
+ const root = join13(dirname(fileURLToPath(import.meta.url)), "..", "..");
1672
1718
  let installed = "unknown";
1673
1719
  try {
1674
- installed = JSON.parse(readFileSync8(join12(root, "package.json"), "utf8")).version;
1720
+ installed = JSON.parse(readFileSync9(join13(root, "package.json"), "utf8")).version;
1675
1721
  } catch {
1676
1722
  }
1677
1723
  console.log(` plugin ${installed} ${root}`);
@@ -1680,7 +1726,9 @@ try {
1680
1726
  console.log(
1681
1727
  ` user ${s.userId ?? "(none \u2014 traces are unattributed)"}` + (s.userIdSource === "none" ? "" : ` [from ${s.userIdSource}]`)
1682
1728
  );
1683
- console.log(` capture ${s.capture ? "ON" : "OFF"} enforce ${s.enforce}`);
1729
+ console.log(
1730
+ ` capture ${s.capture ? "ON" : "OFF"} enforce ${s.enforce} backfill ${s.backfill ? "ON" : "OFF"}`
1731
+ );
1684
1732
  if (s.subagents && s.subagents.found > 0) {
1685
1733
  const { found, shipped } = s.subagents;
1686
1734
  console.log(
@@ -1717,6 +1765,11 @@ try {
1717
1765
  );
1718
1766
  }
1719
1767
  }
1768
+ if (s.pending) {
1769
+ console.log(
1770
+ ` held ${s.pending.transcripts} transcript(s) waiting on the platform since ${s.pending.since}`
1771
+ );
1772
+ }
1720
1773
  if (s.transcripts.length === 0) {
1721
1774
  console.log(" transcripts none shipped yet");
1722
1775
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkhunt-security/endpoint-codex",
3
- "version": "0.9.16",
3
+ "version": "0.9.18",
4
4
  "type": "module",
5
5
  "description": "Darkhunt endpoint adapter for Codex CLI: hook codec, rollout transcript mapper, plugin manifest.",
6
6
  "bin": {
@@ -14,7 +14,7 @@
14
14
  ],
15
15
  "devDependencies": {
16
16
  "@darkhunt-security/endpoint-contracts": "0.9.3",
17
- "@darkhunt-security/endpoint-core": "0.9.3"
17
+ "@darkhunt-security/endpoint-core": "0.9.4"
18
18
  },
19
19
  "publishConfig": {
20
20
  "access": "public",