@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.
- package/.codex-plugin/plugin.json +1 -1
- package/commands/backfill.md +55 -1
- package/commands/status.md +5 -0
- package/dist/bin/backfill.mjs +269 -28
- package/dist/bin/enroll.mjs +12 -1
- package/dist/bin/forwarder.mjs +227 -22
- package/dist/bin/guard.mjs +11 -1
- package/dist/bin/init.mjs +12 -1
- package/dist/bin/spool.mjs +11 -1
- package/dist/bin/status.mjs +79 -26
- package/package.json +2 -2
package/dist/bin/status.mjs
CHANGED
|
@@ -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
|
|
7
|
-
import { dirname, join as
|
|
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:
|
|
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
|
|
1137
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
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 (
|
|
1186
|
-
const lines =
|
|
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:
|
|
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
|
|
1229
|
-
var CLI_CREDENTIALS_PATH =
|
|
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
|
|
1233
|
-
import { basename, join as
|
|
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 [
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
1630
|
-
if (!
|
|
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 =
|
|
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 =
|
|
1717
|
+
const root = join13(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
1672
1718
|
let installed = "unknown";
|
|
1673
1719
|
try {
|
|
1674
|
-
installed = JSON.parse(
|
|
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(
|
|
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.
|
|
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.
|
|
17
|
+
"@darkhunt-security/endpoint-core": "0.9.4"
|
|
18
18
|
},
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"access": "public",
|