@darkhunt-security/endpoint-codex 0.9.5 → 0.9.7

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.5",
3
+ "version": "0.9.7",
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": {
@@ -18474,8 +18474,38 @@ var SessionEmitter = class {
18474
18474
  }
18475
18475
  await this.client.flush();
18476
18476
  }
18477
+ /**
18478
+ * Which subagent this transcript is, if any.
18479
+ *
18480
+ * From the path where the endpoint's layout says so, and otherwise from the file:
18481
+ * Codex names only the parent, so the subagent is identified by the thread the
18482
+ * transcript itself is — `seedKey`, which is exactly that.
18483
+ */
18484
+ agentId() {
18485
+ if (this.options.agentId !== void 0)
18486
+ return this.options.agentId;
18487
+ return this.grouping ? this.options.seedKey ?? this.options.sessionId : void 0;
18488
+ }
18489
+ agentType() {
18490
+ return this.options.agentType ?? this.meta["agentType"];
18491
+ }
18492
+ /**
18493
+ * The agent that spawned this one.
18494
+ *
18495
+ * Claude Code names it outright, from a sidecar the host writes, and it arrives as an
18496
+ * option. Codex never says "parent agent" — but it does not need to: a Codex subagent
18497
+ * is a rollout of its own, so its agent id IS its thread id, and `parent_thread_id`
18498
+ * (carried here as `parentSessionId`) therefore names the parent agent exactly.
18499
+ *
18500
+ * At depth 1 that thread is the session rather than a subagent, so the id names a node
18501
+ * the consumer has as a session and not as an agent. That is the consumer's fallback to
18502
+ * resolve; reporting what the producer actually observed is this side's job.
18503
+ */
18504
+ parentAgentId() {
18505
+ return this.options.parentAgentId ?? this.meta["parentSessionId"];
18506
+ }
18477
18507
  defaultTraceName() {
18478
- const agentType = this.options.agentType ?? this.meta["agentType"];
18508
+ const agentType = this.agentType();
18479
18509
  if (agentType)
18480
18510
  return `subagent: ${agentType}`;
18481
18511
  if (this.options.agentId === void 0) {
@@ -18496,8 +18526,14 @@ var SessionEmitter = class {
18496
18526
  tags: [this.options.vendor, ...this.options.agentId ? ["subagent"] : []],
18497
18527
  metadata: {
18498
18528
  ...this.meta,
18499
- ...this.options.agentId !== void 0 ? { agentId: this.options.agentId } : {},
18500
- ...this.options.agentType !== void 0 ? { agentType: this.options.agentType } : {}
18529
+ // `agent_id` / `agent_type`, not camelCase: trace-hub lifts each metadata
18530
+ // attribute onto the span under its own key, and the consumers that read an
18531
+ // agent out of a span already look for the snake_case names other producers
18532
+ // send. A camelCase key arrives intact and is never found.
18533
+ ...this.agentId() !== void 0 ? { agent_id: this.agentId() } : {},
18534
+ ...this.agentType() !== void 0 ? { agent_type: this.agentType() } : {},
18535
+ ...this.parentAgentId() !== void 0 ? { parent_agent_id: this.parentAgentId() } : {},
18536
+ ...this.options.spawnDepth !== void 0 ? { spawn_depth: this.options.spawnDepth } : {}
18501
18537
  },
18502
18538
  ...this.options.userId !== void 0 ? { userId: this.options.userId } : {},
18503
18539
  ...this.options.userEmail !== void 0 ? { userEmail: this.options.userEmail } : {},
@@ -21650,6 +21686,8 @@ async function runForwarder(mapper, options = {}) {
21650
21686
  passKey: String(from),
21651
21687
  ...sub?.agentId !== void 0 ? { agentId: sub.agentId } : {},
21652
21688
  ...sub?.agentType !== void 0 ? { agentType: sub.agentType } : {},
21689
+ ...sub?.parentAgentId !== void 0 ? { parentAgentId: sub.parentAgentId } : {},
21690
+ ...sub?.spawnDepth !== void 0 ? { spawnDepth: sub.spawnDepth } : {},
21653
21691
  ...ids !== void 0 ? { ids } : {},
21654
21692
  ...userId !== void 0 ? { userId } : {},
21655
21693
  ...carried !== void 0 ? { resumeTurn: carried } : {}
@@ -18474,8 +18474,38 @@ var SessionEmitter = class {
18474
18474
  }
18475
18475
  await this.client.flush();
18476
18476
  }
18477
+ /**
18478
+ * Which subagent this transcript is, if any.
18479
+ *
18480
+ * From the path where the endpoint's layout says so, and otherwise from the file:
18481
+ * Codex names only the parent, so the subagent is identified by the thread the
18482
+ * transcript itself is — `seedKey`, which is exactly that.
18483
+ */
18484
+ agentId() {
18485
+ if (this.options.agentId !== void 0)
18486
+ return this.options.agentId;
18487
+ return this.grouping ? this.options.seedKey ?? this.options.sessionId : void 0;
18488
+ }
18489
+ agentType() {
18490
+ return this.options.agentType ?? this.meta["agentType"];
18491
+ }
18492
+ /**
18493
+ * The agent that spawned this one.
18494
+ *
18495
+ * Claude Code names it outright, from a sidecar the host writes, and it arrives as an
18496
+ * option. Codex never says "parent agent" — but it does not need to: a Codex subagent
18497
+ * is a rollout of its own, so its agent id IS its thread id, and `parent_thread_id`
18498
+ * (carried here as `parentSessionId`) therefore names the parent agent exactly.
18499
+ *
18500
+ * At depth 1 that thread is the session rather than a subagent, so the id names a node
18501
+ * the consumer has as a session and not as an agent. That is the consumer's fallback to
18502
+ * resolve; reporting what the producer actually observed is this side's job.
18503
+ */
18504
+ parentAgentId() {
18505
+ return this.options.parentAgentId ?? this.meta["parentSessionId"];
18506
+ }
18477
18507
  defaultTraceName() {
18478
- const agentType = this.options.agentType ?? this.meta["agentType"];
18508
+ const agentType = this.agentType();
18479
18509
  if (agentType)
18480
18510
  return `subagent: ${agentType}`;
18481
18511
  if (this.options.agentId === void 0) {
@@ -18496,8 +18526,14 @@ var SessionEmitter = class {
18496
18526
  tags: [this.options.vendor, ...this.options.agentId ? ["subagent"] : []],
18497
18527
  metadata: {
18498
18528
  ...this.meta,
18499
- ...this.options.agentId !== void 0 ? { agentId: this.options.agentId } : {},
18500
- ...this.options.agentType !== void 0 ? { agentType: this.options.agentType } : {}
18529
+ // `agent_id` / `agent_type`, not camelCase: trace-hub lifts each metadata
18530
+ // attribute onto the span under its own key, and the consumers that read an
18531
+ // agent out of a span already look for the snake_case names other producers
18532
+ // send. A camelCase key arrives intact and is never found.
18533
+ ...this.agentId() !== void 0 ? { agent_id: this.agentId() } : {},
18534
+ ...this.agentType() !== void 0 ? { agent_type: this.agentType() } : {},
18535
+ ...this.parentAgentId() !== void 0 ? { parent_agent_id: this.parentAgentId() } : {},
18536
+ ...this.options.spawnDepth !== void 0 ? { spawn_depth: this.options.spawnDepth } : {}
18501
18537
  },
18502
18538
  ...this.options.userId !== void 0 ? { userId: this.options.userId } : {},
18503
18539
  ...this.options.userEmail !== void 0 ? { userEmail: this.options.userEmail } : {},
@@ -21650,6 +21686,8 @@ async function runForwarder(mapper, options = {}) {
21650
21686
  passKey: String(from),
21651
21687
  ...sub?.agentId !== void 0 ? { agentId: sub.agentId } : {},
21652
21688
  ...sub?.agentType !== void 0 ? { agentType: sub.agentType } : {},
21689
+ ...sub?.parentAgentId !== void 0 ? { parentAgentId: sub.parentAgentId } : {},
21690
+ ...sub?.spawnDepth !== void 0 ? { spawnDepth: sub.spawnDepth } : {},
21653
21691
  ...ids !== void 0 ? { ids } : {},
21654
21692
  ...userId !== void 0 ? { userId } : {},
21655
21693
  ...carried !== void 0 ? { resumeTurn: carried } : {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkhunt-security/endpoint-codex",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "type": "module",
5
5
  "description": "Darkhunt endpoint adapter for Codex CLI: hook codec, rollout transcript mapper, plugin manifest.",
6
6
  "bin": {