@makaio/client-codex 1.0.0-dev-1779051654000

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +103 -0
  3. package/descriptor.json +21 -0
  4. package/dist/codex-client-session-service-DD2LkxP1.mjs +1551 -0
  5. package/dist/definition.d.ts +90 -0
  6. package/dist/definition.d.ts.map +1 -0
  7. package/dist/index.d.ts +8 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.mjs +4 -0
  10. package/dist/package.d.ts +18 -0
  11. package/dist/package.d.ts.map +1 -0
  12. package/dist/runtime/client-settings.d.ts +149 -0
  13. package/dist/runtime/client-settings.d.ts.map +1 -0
  14. package/dist/runtime/codex-client-session-service.d.ts +148 -0
  15. package/dist/runtime/codex-client-session-service.d.ts.map +1 -0
  16. package/dist/runtime/config-prime-handler.d.ts +37 -0
  17. package/dist/runtime/config-prime-handler.d.ts.map +1 -0
  18. package/dist/runtime/hook-normalizer.d.ts +79 -0
  19. package/dist/runtime/hook-normalizer.d.ts.map +1 -0
  20. package/dist/runtime/namespace.d.ts +193 -0
  21. package/dist/runtime/namespace.d.ts.map +1 -0
  22. package/dist/runtime/package.d.ts +22 -0
  23. package/dist/runtime/package.d.ts.map +1 -0
  24. package/dist/runtime/package.mjs +33 -0
  25. package/dist/runtime/schemas.d.ts +26 -0
  26. package/dist/runtime/schemas.d.ts.map +1 -0
  27. package/dist/runtime/session-config-handler.d.ts +40 -0
  28. package/dist/runtime/session-config-handler.d.ts.map +1 -0
  29. package/dist/runtime/settings-paths.d.ts +43 -0
  30. package/dist/runtime/settings-paths.d.ts.map +1 -0
  31. package/dist/runtime/wiring.d.ts +88 -0
  32. package/dist/runtime/wiring.d.ts.map +1 -0
  33. package/dist/schemas/config.d.ts +306 -0
  34. package/dist/schemas/config.d.ts.map +1 -0
  35. package/dist/schemas/index.d.ts +9 -0
  36. package/dist/schemas/index.d.ts.map +1 -0
  37. package/dist/schemas/wiring.d.ts +108 -0
  38. package/dist/schemas/wiring.d.ts.map +1 -0
  39. package/dist/server.d.ts +3 -0
  40. package/dist/server.d.ts.map +1 -0
  41. package/dist/server.mjs +8 -0
  42. package/dist/src-DkIyzWF3.mjs +19 -0
  43. package/package.json +49 -0
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Client definition for the OpenAI Codex CLI.
3
+ *
4
+ * Codex is a first-party agentic coding assistant binary (`codex`) that
5
+ * Makaio harnesses via the codex-app-server adapter. Capability annotations
6
+ * are derived from `codexCapabilityMap` in `@makaio/contracts` to keep
7
+ * capability taxonomy in a single canonical location.
8
+ * @packageDocumentation
9
+ */
10
+ /**
11
+ * Static client definition for `@makaio/client-codex`.
12
+ *
13
+ * Declares the two native tools the `codex` binary exposes (`bash` and
14
+ * `patch`) and the recommended default approval policy for new harnesses
15
+ * targeting this client.
16
+ */
17
+ export declare const clientDefinition: {
18
+ id: string;
19
+ name: string;
20
+ version: string;
21
+ description?: string | undefined;
22
+ binary?: {
23
+ name: string;
24
+ supportedVersions: string;
25
+ } | undefined;
26
+ nativeTools: {
27
+ name: string;
28
+ friendlyName: string;
29
+ description?: string | undefined;
30
+ category?: string | undefined;
31
+ capabilities: {
32
+ tag: string;
33
+ description?: string | undefined;
34
+ }[];
35
+ }[];
36
+ defaultApprovalPolicy: "always-ask" | "full-access" | "reject";
37
+ logSources?: {
38
+ id: string;
39
+ name: string;
40
+ description?: string | undefined;
41
+ glob?: string | undefined;
42
+ }[] | undefined;
43
+ defaultProviderId?: string | undefined;
44
+ runtimeCapabilities: {
45
+ supportsHooks: boolean;
46
+ supportsStatusline: boolean;
47
+ supportsSupervisorLaunch: boolean;
48
+ supportsManagedBinary: boolean;
49
+ hookEvents: {
50
+ name: string;
51
+ frameworkSubject?: string | undefined;
52
+ }[];
53
+ };
54
+ managedInstall?: {
55
+ type: "npm";
56
+ package: string;
57
+ version: string;
58
+ } | {
59
+ type: "signed-binary-bucket";
60
+ version: string;
61
+ config: {
62
+ baseUrl: string;
63
+ manifestPathTemplate: string;
64
+ manifestSignaturePathTemplate: string;
65
+ publicKeyUrl: string;
66
+ publicKeyFingerprint: string;
67
+ binaryPathTemplate: string;
68
+ platforms: Record<string, string>;
69
+ };
70
+ } | undefined;
71
+ versionCommand?: {
72
+ executable: string | {
73
+ default: string;
74
+ darwin?: string | undefined;
75
+ linux?: string | undefined;
76
+ win32?: string | undefined;
77
+ };
78
+ args: string[];
79
+ } | undefined;
80
+ postInstall?: {
81
+ kind: string;
82
+ payload?: Record<string, unknown> | undefined;
83
+ } | undefined;
84
+ configIsolation?: {
85
+ envVar: string;
86
+ defaultPath: string;
87
+ pathKind: "directory" | "file";
88
+ } | undefined;
89
+ };
90
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwD3B,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { clientDefinition } from './definition.js';
2
+ /** Codex client package descriptor for unified package discovery. */
3
+ export { codexPackage } from './package.js';
4
+ export { AbsolutePathSchema, CodexConfigHooksAddRequestSchema, CodexConfigHooksAddResponseSchema, CodexConfigHooksListRequestSchema, CodexConfigHooksListResponseSchema, CodexConfigHooksRemoveRequestSchema, CodexConfigHooksRemoveResponseSchema, CodexConfigSchemas, CodexHookEntrySchema, CodexNativeCommandHookSchema, CodexNativeHookMatcherGroupSchema, CodexNativeHooksFileSchema, CodexScopeHookRecordSchema, CodexScopeSchema, CodexWiringSchemas, } from './schemas/index.js';
5
+ export type { CodexConfigHooksAddRequest, CodexConfigHooksAddResponse, CodexConfigHooksListRequest, CodexConfigHooksListResponse, CodexConfigHooksRemoveRequest, CodexConfigHooksRemoveResponse, CodexHookEntry, CodexNativeCommandHook, CodexNativeHookMatcherGroup, CodexNativeHooksFile, CodexScope, CodexScopeHookRecord, CodexWiringApplyRequest, CodexWiringListRequest, CodexWiringRemoveRequest, } from './schemas/index.js';
6
+ export { CodexClientSessionService } from './runtime/codex-client-session-service.js';
7
+ export { CodexClientSubjects } from './runtime/namespace.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,gCAAgC,EAChC,iCAAiC,EACjC,iCAAiC,EACjC,kCAAkC,EAClC,mCAAmC,EACnC,oCAAoC,EACpC,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,iCAAiC,EACjC,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,8BAA8B,EAC9B,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,oBAAoB,EACpB,UAAU,EACV,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import { _ as CodexNativeHooksFileSchema, a as CodexWiringSchemas, b as clientDefinition, c as CodexConfigHooksAddResponseSchema, d as CodexConfigHooksRemoveRequestSchema, f as CodexConfigHooksRemoveResponseSchema, g as CodexNativeHookMatcherGroupSchema, h as CodexNativeCommandHookSchema, l as CodexConfigHooksListRequestSchema, m as CodexHookEntrySchema, o as AbsolutePathSchema, p as CodexConfigSchemas, r as CodexClientSubjects, s as CodexConfigHooksAddRequestSchema, t as CodexClientSessionService, u as CodexConfigHooksListResponseSchema, v as CodexScopeHookRecordSchema, y as CodexScopeSchema } from "./codex-client-session-service-DD2LkxP1.mjs";
2
+ import { t as codexPackage } from "./src-DkIyzWF3.mjs";
3
+
4
+ export { AbsolutePathSchema, CodexClientSessionService, CodexClientSubjects, CodexConfigHooksAddRequestSchema, CodexConfigHooksAddResponseSchema, CodexConfigHooksListRequestSchema, CodexConfigHooksListResponseSchema, CodexConfigHooksRemoveRequestSchema, CodexConfigHooksRemoveResponseSchema, CodexConfigSchemas, CodexHookEntrySchema, CodexNativeCommandHookSchema, CodexNativeHookMatcherGroupSchema, CodexNativeHooksFileSchema, CodexScopeHookRecordSchema, CodexScopeSchema, CodexWiringSchemas, clientDefinition, codexPackage };
@@ -0,0 +1,18 @@
1
+ import type { IMakaioBus } from '@makaio/framework/bus';
2
+ /**
3
+ * MakaioNodeExtension<IMakaioBus> descriptor for the Codex client.
4
+ *
5
+ * Wraps the existing {@link clientDefinition} in the standard
6
+ * `MakaioNodeExtension<IMakaioBus>` shape so the runtime coordinator can discover and
7
+ * register this client through the unified client contribution surface.
8
+ */
9
+ import type { MakaioNodeExtension } from '@makaio/framework/contracts';
10
+ /**
11
+ * Package descriptor for the Codex client.
12
+ *
13
+ * Declares the OpenAI Codex CLI binary (`codex`) as a first-party agentic
14
+ * coding assistant client with hook and supervisor-launch support and a
15
+ * default `full-access` approval policy.
16
+ */
17
+ export declare const codexPackage: MakaioNodeExtension<IMakaioBus>;
18
+ //# sourceMappingURL=package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../src/package.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,mBAAmB,CAAC,UAAU,CAKxD,CAAC"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Codex client settings I/O.
3
+ *
4
+ * Provides filesystem read/write operations for Codex `hooks.json`
5
+ * configuration files. Handles both global and project-scoped config files
6
+ * with atomic writes and per-path write serialization to prevent concurrent
7
+ * modification.
8
+ * @packageDocumentation
9
+ */
10
+ import type { CodexScope, CodexConfigHooksListResponse, CodexConfigHooksAddResponse, CodexConfigHooksRemoveResponse } from '../schemas/config.js';
11
+ /**
12
+ * Optional path override injected during testing.
13
+ * When provided, {@link CodexClientSettings} uses these paths instead of
14
+ * calling {@link resolveCodexSettingsPaths}.
15
+ */
16
+ export interface CodexClientSettingsPathsOverride {
17
+ /**
18
+ * Absolute path to the global `hooks.json` file.
19
+ */
20
+ readonly globalHooks: string;
21
+ /**
22
+ * Absolute path to the project-scoped `hooks.json` file, or `null`.
23
+ */
24
+ readonly projectHooks: string | null;
25
+ }
26
+ /**
27
+ * Path resolution options for {@link CodexClientSettings}.
28
+ */
29
+ export interface CodexClientSettingsOptions {
30
+ /** Optional managed Codex config root used for global-scope hooks. */
31
+ readonly configDir?: string;
32
+ /** Optional exact path override used by tests. */
33
+ readonly pathsOverride?: CodexClientSettingsPathsOverride;
34
+ }
35
+ /**
36
+ * Handles reading and writing Codex `hooks.json` configuration files.
37
+ *
38
+ * This is a plain composed component — not a `BaseService` — intended to be
39
+ * instantiated inside `CodexClientSessionService` or a similar host.
40
+ *
41
+ * ## Atomic writes
42
+ * All writes go through a temp-file + `fs.rename()` sequence so that readers
43
+ * never see a partially written file.
44
+ *
45
+ * ## Write serialization
46
+ * A module-scoped per-path mutex ensures that concurrent callers modifying
47
+ * the same file are serialized rather than racing, even across instances.
48
+ */
49
+ export declare class CodexClientSettings {
50
+ /**
51
+ * Optional path override used in tests. When `undefined`, paths are
52
+ * resolved dynamically via {@link resolveCodexSettingsPaths}.
53
+ */
54
+ private readonly pathsOverride;
55
+ /** Optional managed Codex config root for global-scope hooks. */
56
+ private readonly configDir;
57
+ /**
58
+ * Creates a new `CodexClientSettings` instance.
59
+ * @param options - Optional path override or config-root options. Passing
60
+ * `{ globalHooks, projectHooks }` remains supported for existing tests.
61
+ */
62
+ constructor(options?: CodexClientSettingsPathsOverride | CodexClientSettingsOptions);
63
+ /**
64
+ * List the effective hook configuration for a project directory.
65
+ *
66
+ * Reads both the global and (when available) project-scoped config files,
67
+ * concatenates their hooks into an effective list, and returns the per-scope
68
+ * breakdown alongside it.
69
+ * @param req - Request options. `projectDir` is the optional absolute path to
70
+ * the project root (when omitted only the global scope is read).
71
+ * `eventName` is an optional event name filter; when omitted all hooks are
72
+ * returned.
73
+ * @returns Effective merged hook list and per-scope breakdown.
74
+ */
75
+ listHooks(req: {
76
+ projectDir?: string;
77
+ eventName?: string;
78
+ }): Promise<CodexConfigHooksListResponse>;
79
+ /**
80
+ * Add a new hook entry to the specified config scope.
81
+ *
82
+ * The operation is idempotent: if a hook with the same `event`, `command`,
83
+ * and `matcher` already exists in the target file, the file is left
84
+ * unchanged and `{ added: false }` is returned.
85
+ * @param req - Hook entry and targeting options. `scope` selects the config
86
+ * file; `projectDir` is required when `scope` is `'project'`. `event`,
87
+ * `command`, and optional `matcher` / `timeout` form the hook entry.
88
+ * @returns `{ added: true }` when the hook was appended, `{ added: false }`
89
+ * when an identical hook already exists.
90
+ */
91
+ addHook(req: {
92
+ projectDir?: string;
93
+ scope: CodexScope;
94
+ event: string;
95
+ matcher?: string;
96
+ command: string;
97
+ timeout?: number;
98
+ }): Promise<CodexConfigHooksAddResponse>;
99
+ /**
100
+ * Remove hook entries from the specified config scope.
101
+ *
102
+ * Removes all hooks where `entry.event === req.event` and
103
+ * `entry.command.includes(req.match.commandContains)`.
104
+ * @param req - Removal criteria and targeting options. `scope` selects the
105
+ * config file; `projectDir` is required when `scope` is `'project'`.
106
+ * `event` is the event name to match. `match.commandContains` is the
107
+ * command substring filter — any hook whose command contains this string
108
+ * is removed.
109
+ * @returns `{ removed: n }` where `n` is the count of removed hooks.
110
+ */
111
+ removeHook(req: {
112
+ projectDir?: string;
113
+ scope: CodexScope;
114
+ event: string;
115
+ match: {
116
+ commandContains: string;
117
+ };
118
+ }): Promise<CodexConfigHooksRemoveResponse>;
119
+ /**
120
+ * Resolve config file path for a given scope.
121
+ *
122
+ * For `'project'` scope, `projectDir` must be provided. For `'global'`
123
+ * scope, `projectDir` is ignored.
124
+ * @param scope - Target config scope.
125
+ * @param projectDir - Optional absolute path to the project root.
126
+ * @returns Absolute path to the `hooks.json` file for the given scope.
127
+ * @throws When `scope === 'project'` and `projectDir` is absent.
128
+ */
129
+ private resolvePathForScope;
130
+ /**
131
+ * Resolve settings paths, applying the optional test override when present.
132
+ * @param projectDir - Optional project root passed through to
133
+ * {@link resolveCodexSettingsPaths} when no override is active.
134
+ * @returns Resolved settings paths.
135
+ */
136
+ private resolvePaths;
137
+ private isWritable;
138
+ private readHooksFile;
139
+ private readHooksDocument;
140
+ /**
141
+ * Flatten a native Codex hooks document into the public command-hook view.
142
+ * @param document - Native Codex hooks document.
143
+ * @returns Flat command-hook entries ordered by event, matcher group, then
144
+ * handler order.
145
+ */
146
+ private flattenHooksFile;
147
+ private modifyHooksFile;
148
+ }
149
+ //# sourceMappingURL=client-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-settings.d.ts","sourceRoot":"","sources":["../../src/runtime/client-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAEV,UAAU,EAGV,4BAA4B,EAC5B,2BAA2B,EAC3B,8BAA8B,EAC/B,MAAM,sBAAsB,CAAC;AAiB9B;;;;GAIG;AACH,MAAM,WAAW,gCAAgC;IAC/C;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAC3D;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,mBAAmB;IAC9B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA+C;IAC7E,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAE/C;;;;OAIG;IACH,YAAmB,OAAO,CAAC,EAAE,gCAAgC,GAAG,0BAA0B,EAQzF;IAMD;;;;;;;;;;;OAWG;IACU,SAAS,CAAC,GAAG,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CA+B9G;IAED;;;;;;;;;;;OAWG;IACU,OAAO,CAAC,GAAG,EAAE;QACxB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,UAAU,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAsDvC;IAED;;;;;;;;;;;OAWG;IACU,UAAU,CAAC,GAAG,EAAE;QAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,UAAU,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE;YAAE,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC;KACpC,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAqC1C;IAMD;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;YAmBN,UAAU;YAmCV,aAAa;YAeb,iBAAiB;IAmB/B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;YAoCV,eAAe;CAsB9B"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Codex client session normalization service.
3
+ *
4
+ * Subscribes to raw Codex hook events on `client:codex.hook.received` and
5
+ * emits the corresponding normalized `client.session.*` observations via
6
+ * {@link normalizeCodexHook}.
7
+ *
8
+ * Also handles config management requests on `client:codex.config.hooks.*`
9
+ * subjects. Before constructing settings I/O, the service resolves the active
10
+ * config directory via `client.resolveBinary` and uses that as the global
11
+ * Codex config root, falling back to native `~/.codex` paths when no resolver
12
+ * or global binary is available. Wiring requests use the same settings path
13
+ * resolution. The service also handles the blocking `client:codex.config.prime`
14
+ * lifecycle hook and the `client:codex.sessionConfig.setup` delegation subject
15
+ * for per-session config directory initialization.
16
+ *
17
+ * Unknown or not-yet-modeled event names are silently dropped — they stay
18
+ * raw-only inside the `client:codex.*` namespace and are never forwarded to
19
+ * the global `client.*` namespace.
20
+ *
21
+ * ## Adapter-managed session gate
22
+ *
23
+ * When both the native-hook ingress and the adapter-derived path are active for
24
+ * the same Codex process, `client.session.started` would otherwise be emitted
25
+ * twice. The service listens to `client.runtime.started` events: when an event
26
+ * arrives with `clientId === CLIENT_ID`, `source.layer === 'adapter'`, and a
27
+ * non-empty `adapterSessionId`, that session ID is recorded as adapter-managed.
28
+ * Any subsequent normalized hook for the same `adapterSessionId` is then
29
+ * silently dropped — the adapter path already owns the canonical emission.
30
+ * Sessions whose `adapterSessionId` is absent or not yet registered emit as
31
+ * before (fail-open). Events from other clients (e.g. `'claude-code'`,
32
+ * `'gemini'`) are ignored unconditionally — their adapter sessions must not
33
+ * suppress Codex hook emissions.
34
+ *
35
+ * The managed-session set is bounded at {@link MANAGED_SESSION_CAP} entries to
36
+ * prevent unbounded growth in long-lived processes. When the cap is reached,
37
+ * the oldest recorded session ID is evicted before inserting the new one
38
+ * (FIFO).
39
+ * @packageDocumentation
40
+ */
41
+ import type { IMakaioBus } from '@makaio/framework/bus';
42
+ import { BaseService } from '@makaio/framework/service-base';
43
+ import { CodexClientSettings } from './client-settings.js';
44
+ /**
45
+ * Maximum number of adapter-managed session IDs retained in
46
+ * {@link CodexClientSessionService.managedAdapterSessionIds}.
47
+ *
48
+ * Concurrent active Codex sessions are typically single-digit, so this
49
+ * cap is a safety net against unbounded growth in long-lived processes. When
50
+ * the cap is reached, the oldest recorded ID is evicted (FIFO) before the new
51
+ * one is inserted.
52
+ */
53
+ export declare const MANAGED_SESSION_CAP = 10000;
54
+ /**
55
+ * Service that normalizes raw Codex hook events into global
56
+ * `client.session.*` observed-semantics events and handles Codex config
57
+ * management requests on `client:codex.config.hooks.*`.
58
+ *
59
+ * Lifecycle:
60
+ * 1. `init()` — subscribes to `client:codex.hook.received`, subscribes to
61
+ * `client.runtime.started` for the adapter-managed session gate, and
62
+ * registers request handlers for `config.hooks.list`, `config.hooks.add`,
63
+ * `config.hooks.remove`, `config.prime`, `wiring.list`, `wiring.apply`,
64
+ * `wiring.remove`, and `sessionConfig.setup`.
65
+ * 2. On each incoming raw event, calls {@link normalizeCodexHook}.
66
+ * 3. Emits the normalized subject when the event is recognized; silently
67
+ * ignores unknown events. Normalized `client.session.*` events are
68
+ * suppressed when the `adapterSessionId` is already in the adapter-managed
69
+ * set.
70
+ * 4. `destroy()` — unsubscribes all handlers automatically via `BaseService`.
71
+ */
72
+ export declare class CodexClientSessionService extends BaseService {
73
+ /** Optional injected settings I/O delegate for tests. */
74
+ private readonly settingsOverride;
75
+ /** Cached active config-dir resolution; reset when the active Codex version changes. */
76
+ private cachedConfigDir;
77
+ /**
78
+ * Set of `adapterSessionId` values known to be owned by an adapter-managed
79
+ * Codex runtime. Populated by {@link handleRuntimeStarted} when a
80
+ * `client.runtime.started` event arrives with `clientId === CLIENT_ID` and
81
+ * `source.layer === 'adapter'`.
82
+ *
83
+ * Bounded at {@link MANAGED_SESSION_CAP} entries — the oldest ID is evicted
84
+ * (FIFO) when the cap is reached.
85
+ *
86
+ * Used by {@link handleHookReceived} to gate duplicate `client.session.*`
87
+ * emissions for sessions that the adapter path already covers.
88
+ */
89
+ private readonly managedAdapterSessionIds;
90
+ /**
91
+ * Creates a new Codex client session service.
92
+ * @param bus - Bus instance used for subscribing and emitting events
93
+ * @param settings - Optional {@link CodexClientSettings} instance for tests
94
+ * that need exact filesystem paths. Production callers should omit it so
95
+ * the service can resolve the active managed config dir via the bus.
96
+ */
97
+ constructor(bus?: IMakaioBus, settings?: CodexClientSettings);
98
+ /**
99
+ * Register the raw hook ingress handler, config management request handlers,
100
+ * wiring management request handlers, the config-prime lifecycle handler,
101
+ * and the session config setup handler on the bus.
102
+ *
103
+ * Also subscribes to `client.runtime.started` to track adapter-managed
104
+ * sessions for the {@link handleHookReceived} suppression gate.
105
+ */
106
+ protected onInit(): void;
107
+ /**
108
+ * Clear the adapter-managed session ID set on teardown.
109
+ */
110
+ protected onDestroy(): void;
111
+ private createSettings;
112
+ /**
113
+ * Return the cached config directory promise, resolving it on first access.
114
+ *
115
+ * Missing binary resolution is a graceful fallback so config reads/writes can
116
+ * still target native Codex config paths in framework-only or global-only
117
+ * setups.
118
+ * @returns Absolute managed config dir, or `undefined` to use native paths.
119
+ */
120
+ private resolveConfigDir;
121
+ private doResolveConfigDir;
122
+ /**
123
+ * Record a runtime as adapter-managed when the evidence source is an adapter.
124
+ *
125
+ * Called for every `client.runtime.started` event. Only events whose
126
+ * `clientId` equals `'codex'`, whose `source.layer` is `'adapter'`, and
127
+ * that carry a non-empty `adapterSessionId` update the managed-sessions gate.
128
+ * Events from other clients (e.g. `'claude-code'`, `'gemini'`) are ignored
129
+ * unconditionally — their adapter sessions must not suppress Codex hook
130
+ * emissions. Non-adapter sources (e.g. `'supervisor'`, `'statusline'`) are
131
+ * also ignored to prevent accidental suppression of native hook paths.
132
+ *
133
+ * When the set reaches {@link MANAGED_SESSION_CAP}, the oldest entry is
134
+ * evicted before the new ID is inserted.
135
+ * @param payload - `client.runtime.started` payload
136
+ */
137
+ private handleRuntimeStarted;
138
+ private handleHookReceived;
139
+ /**
140
+ * Determine whether a normalized native hook belongs to an adapter-managed
141
+ * session whose global observed-semantics events are already emitted by the
142
+ * adapter layer.
143
+ * @param adapterSessionId - Adapter/session identifier from the normalized hook
144
+ * @returns True when the native hook should remain raw-only
145
+ */
146
+ private isAdapterManagedSession;
147
+ }
148
+ //# sourceMappingURL=codex-client-session-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-client-session-service.d.ts","sourceRoot":"","sources":["../../src/runtime/codex-client-session-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAU3D;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,yBAA0B,SAAQ,WAAW;IACxD,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,wFAAwF;IACxF,OAAO,CAAC,eAAe,CAA0C;IAEjE;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAqB;IAE9D;;;;;;OAMG;IACH,YAAmB,GAAG,GAAE,UAAsB,EAAE,QAAQ,CAAC,EAAE,mBAAmB,EAG7E;IAED;;;;;;;OAOG;IACH,UAAmB,MAAM,IAAI,IAAI,CA+DhC;IAED;;OAEG;IACH,UAAmB,SAAS,IAAI,IAAI,CAGnC;YAMa,cAAc;IAQ5B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;YA0BV,kBAAkB;IAgBhC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,oBAAoB;YA0Bd,kBAAkB;IAgChC;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;CAGhC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Codex config-prime handler.
3
+ *
4
+ * Handles the `client:codex.config.prime` delegation subject fired by the
5
+ * framework at three lifecycle phases: `managed-install`, `profile-create`,
6
+ * and `session-create`.
7
+ *
8
+ * The handler ensures that `check_for_update_on_startup = false` is present
9
+ * in the Codex `config.toml` file inside the target directory so that managed
10
+ * Codex processes never attempt to auto-update during a Makaio-controlled
11
+ * session. All other existing config keys are preserved; the key is replaced
12
+ * when it already exists with any value, and appended when absent.
13
+ *
14
+ * Writes are atomic (tmp-file + rename) to prevent readers from observing a
15
+ * partially written file. The operation is idempotent: when the file already
16
+ * contains the correct value the write is skipped entirely.
17
+ * @packageDocumentation
18
+ */
19
+ import type { ClientConfigPrimeRequest, ClientConfigPrimeResponse } from '@makaio/framework/contracts/client';
20
+ /**
21
+ * Prime the Codex `config.toml` in the target config directory.
22
+ *
23
+ * Ensures that `check_for_update_on_startup = false` is set, preserving all
24
+ * other existing key-value pairs. Existing occurrences of the key (with any
25
+ * value) are replaced; the key is appended when absent. Empty lines are
26
+ * stripped to keep the file compact.
27
+ *
28
+ * The write is atomic via a temporary file + `fs.rename()` to prevent readers
29
+ * from observing a partially written file. The operation is idempotent: when
30
+ * the file already contains the correct value the disk is not touched.
31
+ * @param payload - Config prime request containing `clientId`, `configDir`,
32
+ * and `phase`. Additional optional fields (`binaryVersion`, `adapterName`,
33
+ * `projectDir`) are accepted but not used by the Codex prime handler.
34
+ * @returns `{ primed: true }` on success.
35
+ */
36
+ export declare function handleCodexConfigPrime(payload: ClientConfigPrimeRequest): Promise<ClientConfigPrimeResponse>;
37
+ //# sourceMappingURL=config-prime-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-prime-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/config-prime-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAMpG;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAmClH"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Pure normalizer for Codex CLI hook events.
3
+ *
4
+ * Maps the Codex-native hook event names emitted on
5
+ * `client:codex.hook.received` to their corresponding
6
+ * `client.session.*` observed-semantics subjects.
7
+ *
8
+ * **Mapping table** (Codex event → global subject):
9
+ *
10
+ * | Codex event name | Global subject |
11
+ * |--------------------------|------------------------------------------|
12
+ * | `SessionStart` | `client.session.started` |
13
+ * | `UserPromptSubmit` | `client.session.userPrompt.submitted` |
14
+ * | `Stop` | `client.session.turn.completed` |
15
+ * | `PreToolUse` | `client.session.tool.pre` |
16
+ * | `PostToolUse` | `client.session.tool.post` |
17
+ *
18
+ * All other event names are returned as `null` — they are kept raw only and
19
+ * are never emitted into the global `client.*` namespace.
20
+ *
21
+ * **Source notes:** The Codex CLI hook event names above reflect the OpenAI
22
+ * Codex CLI hook system as documented at the time of authoring. If the binary
23
+ * changes its hook names, update {@link CODEX_EVENT_MAP} accordingly.
24
+ * @packageDocumentation
25
+ */
26
+ import { ClientSubjects } from '@makaio/framework/clients';
27
+ import type { ClientSessionStarted, ClientSessionUserPromptSubmitted, ClientSessionTurnCompleted, ClientSessionToolPre, ClientSessionToolPost } from '@makaio/framework/contracts/client';
28
+ import type { RawClientHookPayload } from './schemas.js';
29
+ /**
30
+ * Union of all normalized subject definitions the Codex normalizer can emit.
31
+ *
32
+ * Used as the return type of {@link normalizeCodexHook} to keep downstream
33
+ * consumers type-safe without wide `SubjectDefinition` casts.
34
+ */
35
+ export type CodexNormalizedSubject = typeof ClientSubjects.session.started | typeof ClientSubjects.session.userPrompt.submitted | typeof ClientSubjects.session.turn.completed | typeof ClientSubjects.session.tool.pre | typeof ClientSubjects.session.tool.post;
36
+ /**
37
+ * Union of all normalized payload types the Codex normalizer can produce.
38
+ *
39
+ * Mirrors the `client.session.*` schema union so callers do not need to
40
+ * import individual payload types from `@makaio/contracts`.
41
+ */
42
+ export type CodexNormalizedPayload = ClientSessionStarted | ClientSessionUserPromptSubmitted | ClientSessionTurnCompleted | ClientSessionToolPre | ClientSessionToolPost;
43
+ /**
44
+ * Discriminated union of normalized Codex hook event results.
45
+ *
46
+ * Each variant pairs a specific `client.session.*` subject with its
47
+ * corresponding strongly-typed payload. The caller switches on `subject`
48
+ * to obtain a narrowed payload type and call `bus.emit` without casts.
49
+ *
50
+ * When the event name is unknown, {@link normalizeCodexHook} returns `null`
51
+ * to signal that the event must stay raw-only.
52
+ */
53
+ export type CodexNormalizedEvent = {
54
+ readonly subject: typeof ClientSubjects.session.started;
55
+ readonly payload: ClientSessionStarted;
56
+ } | {
57
+ readonly subject: typeof ClientSubjects.session.userPrompt.submitted;
58
+ readonly payload: ClientSessionUserPromptSubmitted;
59
+ } | {
60
+ readonly subject: typeof ClientSubjects.session.turn.completed;
61
+ readonly payload: ClientSessionTurnCompleted;
62
+ } | {
63
+ readonly subject: typeof ClientSubjects.session.tool.pre;
64
+ readonly payload: ClientSessionToolPre;
65
+ } | {
66
+ readonly subject: typeof ClientSubjects.session.tool.post;
67
+ readonly payload: ClientSessionToolPost;
68
+ };
69
+ /**
70
+ * Normalize a raw Codex hook payload into a `client.session.*` event.
71
+ *
72
+ * Returns `null` for unknown or not-yet-modeled event names so the caller
73
+ * skips global emission and keeps the event raw-only in `client:codex.*`.
74
+ * @param raw - Raw hook payload delivered on `client:codex.hook.received`
75
+ * @returns Normalized event with subject and typed payload, or `null` when
76
+ * the event name is unknown
77
+ */
78
+ export declare function normalizeCodexHook(raw: RawClientHookPayload): CodexNormalizedEvent | null;
79
+ //# sourceMappingURL=hook-normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-normalizer.d.ts","sourceRoot":"","sources":["../../src/runtime/hook-normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,cAAc,EAAsB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,gCAAgC,EAChC,0BAA0B,EAC1B,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAC9B,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,GACrC,OAAO,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,GAClD,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,GAC5C,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,GACtC,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAC9B,oBAAoB,GACpB,gCAAgC,GAChC,0BAA0B,GAC1B,oBAAoB,GACpB,qBAAqB,CAAC;AAE1B;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,GACnG;IACE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;IACrE,QAAQ,CAAC,OAAO,EAAE,gCAAgC,CAAC;CACpD,GACD;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,CAAA;CAAE,GAChH;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,GACpG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAqE3G;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,oBAAoB,GAAG,oBAAoB,GAAG,IAAI,CAkDzF"}