@principles/codex-adapter 0.2.8 → 0.3.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.
@@ -77,9 +77,11 @@ export function decodeCodexInput(raw) {
77
77
  if (kind === 'before_tool_call' || kind === 'after_tool_call') {
78
78
  const toolName = requiredString(raw, 'tool_name');
79
79
  const toolInput = requiredUnknown(raw, 'tool_input');
80
- requiredString(raw, 'tool_use_id');
80
+ // PRI-750: Codex `tool_use_id` is required and host-authoritative — keep it
81
+ // on the shared context so the receipt chain can bind tools to turns.
82
+ const toolCallId = requiredString(raw, 'tool_use_id');
81
83
  const toolOutput = kind === 'after_tool_call' ? requiredUnknown(raw, 'tool_response') : undefined;
82
- context = { ...common, toolName, toolInput, ...(kind === 'after_tool_call' ? { toolOutput } : {}) };
84
+ context = { ...common, toolName, toolCallId, toolInput, ...(kind === 'after_tool_call' ? { toolOutput } : {}) };
83
85
  rawPayload = { toolInput: { toolName, params: toolInput } };
84
86
  }
85
87
  else if (kind === 'before_prompt_build') {
package/dist/pd-hook.js CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync } from 'node:fs';
3
+ import path from 'node:path';
3
4
  import process from 'node:process';
4
5
  import { pathToFileURL } from 'node:url';
6
+ import { appendEventLogLine, redactTelemetryString } from '@principles/core/runtime-v2';
5
7
  import { createProductionHostRuntime, loadPdConfigForPlugin, resolveNearestPdWorkspace } from '@principles/host-runtime';
6
8
  import { CODEX_TOOL_SEMANTICS } from './tool-semantics.js';
7
9
  import { computeFeatureFlagsFromConfig } from '@principles/core/runtime-v2';
@@ -9,6 +11,40 @@ import { CodexHooksHostAdapter } from './host-adapter.js';
9
11
  import { CodexDecoderError, CodexEncoderError } from './codec/index.js';
10
12
  import { ingestCodexConversation } from './ingestion/ingestion.js';
11
13
  import { runGovernanceAdmission } from './ingestion/admission.js';
14
+ /**
15
+ * PRI-750: event emitter for the Codex subprocess model. Writes the same
16
+ * `events_<date>.jsonl` line shape as the OpenClaw EventLog via the core
17
+ * writer, so the Codex host path stays independent of the OpenClaw plugin
18
+ * (codex-adapter must not depend on principles-disciple — bundle guard).
19
+ */
20
+ function codexEventEmitter(stateDir) {
21
+ return {
22
+ recordRuntimeV2ActivationsInjected(data) {
23
+ appendEventLogLine(stateDir, {
24
+ ts: new Date().toISOString(),
25
+ type: 'runtime_v2_prompt_activations_injected',
26
+ category: 'injected',
27
+ sessionId: data.sessionId,
28
+ data,
29
+ });
30
+ },
31
+ recordToolCall(sessionId, data) {
32
+ // rc-8: tool events are telemetry — redact every string field before
33
+ // persisting (same policy as the OpenClaw EventLog redactEventData).
34
+ const redacted = {};
35
+ for (const [key, value] of Object.entries(data)) {
36
+ redacted[key] = typeof value === 'string' ? redactTelemetryString(value) : value;
37
+ }
38
+ appendEventLogLine(stateDir, {
39
+ ts: new Date().toISOString(),
40
+ type: 'tool_call',
41
+ category: data.error || (data.exitCode !== undefined && data.exitCode !== 0) ? 'failure' : 'success',
42
+ sessionId,
43
+ data: redacted,
44
+ });
45
+ },
46
+ };
47
+ }
12
48
  const MAX_DIAGNOSTIC = 500;
13
49
  function diagnostic(reason, nextAction) {
14
50
  const boundedReason = reason.replace(/\s+/g, ' ').trim().slice(0, MAX_DIAGNOSTIC);
@@ -118,7 +154,16 @@ export async function processHookInvocation(rawStdin, _env = process.env, cwd =
118
154
  const ingestionDiagnostics = ingestionEnabled
119
155
  ? await runConversationIngestion({ rawPayload: parsed, kind: event.kind, workspaceDir: resolution.workspaceDir, env: _env })
120
156
  : [];
121
- const result = await createProductionHostRuntime({ hostKind: 'codex', toolSemantics: CODEX_TOOL_SEMANTICS }).dispatch(event);
157
+ // PRI-750: emit shared-path injection/tool events with the host's natural
158
+ // turn/tool ids (turn_id → runId, tool_use_id → toolCallId) through the core
159
+ // event-JSONL writer (same events_*.jsonl format as the OpenClaw EventLog;
160
+ // the Codex adapter stays independent of the OpenClaw plugin). The line
161
+ // writer appends synchronously — no flush/dispose needed for the subprocess.
162
+ const result = await createProductionHostRuntime({
163
+ hostKind: 'codex',
164
+ toolSemantics: CODEX_TOOL_SEMANTICS,
165
+ events: codexEventEmitter(path.join(resolution.workspaceDir, '.state')),
166
+ }).dispatch(event);
122
167
  const stderr = [...(result.warnings ?? []).slice(0, 16).map((warning) => diagnostic(warning, 'Inspect PD Workspace state and retry; the hook failed open.')), ...ingestionDiagnostics];
123
168
  return { stdout: adapter.encodeOutput(result, event.kind), exitCode: 0, stderr };
124
169
  }
@@ -213,6 +213,9 @@ export async function runCodexWorkspaceWorkerCycle(options) {
213
213
  logger,
214
214
  emitEvent,
215
215
  toolSemantics: CODEX_TOOL_SEMANTICS,
216
+ // PRI-741: artificer generation gets the Codex host projection
217
+ // (Bash/apply_patch — evidence-bound, intentionally sparse).
218
+ hostKinds: ['codex'],
216
219
  // No hostToolCatalog: PD has not declared a Codex tool catalog; a wrong
217
220
  // (OpenClaw) catalog would be worse than none (PRI-630 follow-up).
218
221
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principles/codex-adapter",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
4
4
  "description": "Codex CLI host adapter for Principles Disciple — implements HostAdapter interface for OpenAI Codex CLI's stdin/stdout JSON hook model (ADR-0020).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,7 +32,8 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@principles/core": "^1.74.1",
35
- "@principles/host-runtime": "^0.1.0"
35
+ "@principles/host-runtime": "^0.1.0",
36
+ "@principles/install-layout": "^0.2.0"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@types/node": "^26.4.1",